@php-wasm/universal 3.0.21 → 3.0.29
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/index.cjs +6 -6
- package/index.cjs.map +1 -1
- package/index.js +199 -136
- package/index.js.map +1 -1
- package/lib/fs-helpers.d.ts +2 -1
- package/lib/index.d.ts +10 -2
- package/lib/load-php-runtime.d.ts +34 -1
- package/lib/php-instance-manager.d.ts +38 -0
- package/lib/php-process-manager.d.ts +3 -6
- package/lib/php-request-handler.d.ts +19 -18
- package/lib/php.d.ts +2 -1
- package/lib/sandboxed-spawn-handler-factory.d.ts +7 -2
- package/lib/single-php-instance-manager.d.ts +34 -0
- package/lib/supported-php-versions.d.ts +2 -2
- package/package.json +9 -9
package/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/universal/src/lib/rethrow-file-system-error.ts","../../../../packages/php-wasm/universal/src/lib/fs-helpers.ts","../../../../packages/php-wasm/universal/src/lib/php-worker.ts","../../../../packages/php-wasm/universal/src/lib/is-exit-code.ts","../../../../packages/php-wasm/universal/src/lib/load-php-runtime.ts","../../../../packages/php-wasm/universal/src/lib/php-response.ts","../../../../packages/php-wasm/universal/src/lib/error-event-polyfill.ts","../../../../packages/php-wasm/universal/src/lib/wasm-error-reporting.ts","../../../../packages/php-wasm/universal/src/lib/php.ts","../../../../packages/php-wasm/universal/src/lib/ini.ts","../../../../packages/php-wasm/universal/src/lib/error-reporting.ts","../../../../packages/php-wasm/universal/src/lib/http-cookie-store.ts","../../../../packages/php-wasm/universal/src/lib/stream-read-file-from-php.ts","../../../../packages/php-wasm/universal/src/lib/iterate-files.ts","../../../../packages/php-wasm/universal/src/lib/write-files-stream-to-php.ts","../../../../packages/php-wasm/universal/src/lib/php-process-manager.ts","../../../../packages/php-wasm/universal/src/lib/supported-php-versions.ts","../../../../packages/php-wasm/universal/src/lib/urls.ts","../../../../packages/php-wasm/universal/src/lib/encode-as-multipart.ts","../../../../packages/php-wasm/universal/src/lib/php-request-handler.ts","../../../../packages/php-wasm/universal/src/lib/rotate-php-runtime.ts","../../../../packages/php-wasm/universal/src/lib/write-files.ts","../../../../packages/php-wasm/universal/src/lib/proxy-file-system.ts","../../../../packages/php-wasm/universal/src/lib/sandboxed-spawn-handler-factory.ts","../../../../packages/php-wasm/universal/src/lib/comlink-sync.ts","../../../../packages/php-wasm/universal/src/lib/serialize-error.ts","../../../../packages/php-wasm/universal/src/lib/api.ts"],"sourcesContent":["/**\n * Emscripten's filesystem-related Exception.\n *\n * @see https://emscripten.org/docs/api_reference/Filesystem-API.html\n * @see https://github.com/emscripten-core/emscripten/blob/main/system/lib/libc/musl/arch/emscripten/bits/errno.h\n * @see https://github.com/emscripten-core/emscripten/blob/38eedc630f17094b3202fd48ac0c2c585dbea31e/system/include/wasi/api.h#L336\n */\n\nexport class ErrnoError extends Error {\n\tconstructor(errno: number, message?: string, options?: any) {\n\t\tsuper(message, options);\n\t\tthis.name = 'ErrnoError';\n\t\tthis.errno = errno;\n\t}\n\n\tnode?: any;\n\terrno: number;\n}\n/**\n * @see https://github.com/emscripten-core/emscripten/blob/38eedc630f17094b3202fd48ac0c2c585dbea31e/system/include/wasi/api.h#L336\n */\nexport const FileErrorCodes = {\n\t0: 'No error occurred. System call completed successfully.',\n\t1: 'Argument list too long.',\n\t2: 'Permission denied.',\n\t3: 'Address in use.',\n\t4: 'Address not available.',\n\t5: 'Address family not supported.',\n\t6: 'Resource unavailable, or operation would block.',\n\t7: 'Connection already in progress.',\n\t8: 'Bad file descriptor.',\n\t9: 'Bad message.',\n\t10: 'Device or resource busy.',\n\t11: 'Operation canceled.',\n\t12: 'No child processes.',\n\t13: 'Connection aborted.',\n\t14: 'Connection refused.',\n\t15: 'Connection reset.',\n\t16: 'Resource deadlock would occur.',\n\t17: 'Destination address required.',\n\t18: 'Mathematics argument out of domain of function.',\n\t19: 'Reserved.',\n\t20: 'File exists.',\n\t21: 'Bad address.',\n\t22: 'File too large.',\n\t23: 'Host is unreachable.',\n\t24: 'Identifier removed.',\n\t25: 'Illegal byte sequence.',\n\t26: 'Operation in progress.',\n\t27: 'Interrupted function.',\n\t28: 'Invalid argument.',\n\t29: 'I/O error.',\n\t30: 'Socket is connected.',\n\t31: 'There is a directory under that path.',\n\t32: 'Too many levels of symbolic links.',\n\t33: 'File descriptor value too large.',\n\t34: 'Too many links.',\n\t35: 'Message too large.',\n\t36: 'Reserved.',\n\t37: 'Filename too long.',\n\t38: 'Network is down.',\n\t39: 'Connection aborted by network.',\n\t40: 'Network unreachable.',\n\t41: 'Too many files open in system.',\n\t42: 'No buffer space available.',\n\t43: 'No such device.',\n\t44: 'There is no such file or directory OR the parent directory does not exist.',\n\t45: 'Executable file format error.',\n\t46: 'No locks available.',\n\t47: 'Reserved.',\n\t48: 'Not enough space.',\n\t49: 'No message of the desired type.',\n\t50: 'Protocol not available.',\n\t51: 'No space left on device.',\n\t52: 'Function not supported.',\n\t53: 'The socket is not connected.',\n\t54: 'Not a directory or a symbolic link to a directory.',\n\t55: 'Directory not empty.',\n\t56: 'State not recoverable.',\n\t57: 'Not a socket.',\n\t58: 'Not supported, or operation not supported on socket.',\n\t59: 'Inappropriate I/O control operation.',\n\t60: 'No such device or address.',\n\t61: 'Value too large to be stored in data type.',\n\t62: 'Previous owner died.',\n\t63: 'Operation not permitted.',\n\t64: 'Broken pipe.',\n\t65: 'Protocol error.',\n\t66: 'Protocol not supported.',\n\t67: 'Protocol wrong type for socket.',\n\t68: 'Result too large.',\n\t69: 'Read-only file system.',\n\t70: 'Invalid seek.',\n\t71: 'No such process.',\n\t72: 'Reserved.',\n\t73: 'Connection timed out.',\n\t74: 'Text file busy.',\n\t75: 'Cross-device link.',\n\t76: 'Extension: Capabilities insufficient.',\n} as any;\n\nexport function getEmscriptenFsError(e: any) {\n\tconst errno = typeof e === 'object' ? ((e as any)?.errno as any) : null;\n\tif (errno in FileErrorCodes) {\n\t\treturn FileErrorCodes[errno];\n\t}\n}\n\nexport function rethrowFileSystemError(messagePrefix = '') {\n\treturn function catchFileSystemError(value: (...args: any[]) => any) {\n\t\treturn function (...args: any[]) {\n\t\t\ttry {\n\t\t\t\t// @ts-expect-error Parameter 'this' implicitly has an 'any' type.ts(7006)\n\t\t\t\treturn value.apply(this, args);\n\t\t\t} catch (e) {\n\t\t\t\tconst errno =\n\t\t\t\t\ttypeof e === 'object' ? ((e as any)?.errno as any) : null;\n\t\t\t\tif (errno in FileErrorCodes) {\n\t\t\t\t\tconst errmsg = FileErrorCodes[errno];\n\t\t\t\t\tconst path = typeof args[1] === 'string' ? args[1] : null;\n\t\t\t\t\tconst formattedPrefix =\n\t\t\t\t\t\tpath !== null\n\t\t\t\t\t\t\t? messagePrefix.replaceAll('{path}', path)\n\t\t\t\t\t\t\t: messagePrefix;\n\t\t\t\t\tthrow new ErrnoError(\n\t\t\t\t\t\terrno,\n\t\t\t\t\t\t`${formattedPrefix}: ${errmsg}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: e,\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t};\n\t};\n}\n","import type { Emscripten } from './emscripten-types';\nimport {\n\tErrnoError,\n\tgetEmscriptenFsError,\n\trethrowFileSystemError,\n} from './rethrow-file-system-error';\nimport { logger } from '@php-wasm/logger';\nimport { dirname, joinPaths } from '@php-wasm/util';\n\nexport interface RmDirOptions {\n\t/**\n\t * If true, recursively removes the directory and all its contents.\n\t * Default: true.\n\t */\n\trecursive?: boolean;\n}\n\nexport interface ListFilesOptions {\n\t/**\n\t * If true, prepend given folder path to all file names.\n\t * Default: false.\n\t */\n\tprependPath: boolean;\n}\n\nexport class FSHelpers {\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as a string.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param FS\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\tstatic readFileAsText(FS: Emscripten.RootFS, path: string) {\n\t\treturn new TextDecoder().decode(FSHelpers.readFileAsBuffer(FS, path));\n\t}\n\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as an array buffer.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param FS\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\tstatic readFileAsBuffer(FS: Emscripten.RootFS, path: string): Uint8Array {\n\t\treturn FS.readFile(path);\n\t}\n\n\t/**\n\t * Overwrites data in a file in the PHP filesystem.\n\t * Creates a new file if one doesn't exist yet.\n\t *\n\t * @param FS\n\t * @param path - The file path to write to.\n\t * @param data - The data to write to the file.\n\t */\n\tstatic writeFile(\n\t\tFS: Emscripten.RootFS,\n\t\tpath: string,\n\t\tdata: string | Uint8Array\n\t) {\n\t\tFS.writeFile(path, data);\n\t}\n\n\t/**\n\t * Removes a file from the PHP filesystem.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param FS\n\t * @param path - The file path to remove.\n\t */\n\tstatic unlink(FS: Emscripten.RootFS, path: string) {\n\t\tFS.unlink(path);\n\t}\n\n\t/**\n\t * Moves a file or directory in the PHP filesystem to a\n\t * new location.\n\t *\n\t * @param FS\n\t * @param fromPath The path to rename.\n\t * @param toPath The new path.\n\t */\n\tstatic mv(FS: Emscripten.RootFS, fromPath: string, toPath: string) {\n\t\ttry {\n\t\t\t// FS.rename moves the inode within the same filesystem.\n\t\t\t// If fromPath and toPath are on different filesystems,\n\t\t\t// the operation will fail. In that case, we need to do\n\t\t\t// a recursive copy of all the files and remove the original.\n\t\t\t// Note this is also what happens in the linux `mv` command.\n\t\t\tconst fromMount = FS.lookupPath(fromPath).node.mount;\n\t\t\tconst toMount = FSHelpers.fileExists(FS, toPath)\n\t\t\t\t? FS.lookupPath(toPath).node.mount\n\t\t\t\t: FS.lookupPath(dirname(toPath)).node.mount;\n\t\t\tconst movingBetweenFilesystems =\n\t\t\t\tfromMount.mountpoint !== toMount.mountpoint;\n\n\t\t\tif (movingBetweenFilesystems) {\n\t\t\t\tFSHelpers.copyRecursive(FS, fromPath, toPath);\n\t\t\t\tif (FSHelpers.isDir(FS, fromPath)) {\n\t\t\t\t\tFSHelpers.rmdir(FS, fromPath, { recursive: true });\n\t\t\t\t} else {\n\t\t\t\t\tFS.unlink(fromPath);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tFS.rename(fromPath, toPath);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconst errmsg = getEmscriptenFsError(e);\n\t\t\tif (!errmsg) {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Could not move ${fromPath} to ${toPath}: ${errmsg}`,\n\t\t\t\t{\n\t\t\t\t\tcause: e,\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Removes a directory from the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path The directory path to remove.\n\t * @param options Options for the removal.\n\t */\n\tstatic rmdir(\n\t\tFS: Emscripten.RootFS,\n\t\tpath: string,\n\t\toptions: RmDirOptions = { recursive: true }\n\t) {\n\t\t/**\n\t\t * Mount points cannot be removed and will throw a ErrnoError with\n\t\t * the code 10 (EBUSY).\n\t\t * To prevent the recursive option from removing internal files before\n\t\t * failing to remove the mount point, we need to check if the path is a\n\t\t * mount point and throw an error early.\n\t\t *\n\t\t * Because a mountpoint can be a symlink, we should not follow it.\n\t\t * Otherwise, a mounted sylink would point to the symlinked path,\n\t\t * instead of the mountpoint.\n\t\t */\n\t\tconst mountPoint = FS.lookupPath(path, { follow: false });\n\t\tif (mountPoint?.node.mount.mountpoint === path) {\n\t\t\tthrow new ErrnoError(10);\n\t\t}\n\n\t\tif (options?.recursive) {\n\t\t\tFSHelpers.listFiles(FS, path).forEach((file) => {\n\t\t\t\tconst filePath = `${path}/${file}`;\n\t\t\t\tif (FSHelpers.isDir(FS, filePath)) {\n\t\t\t\t\tFSHelpers.rmdir(FS, filePath, options);\n\t\t\t\t} else {\n\t\t\t\t\tFSHelpers.unlink(FS, filePath);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (FS.getPath(FS.lookupPath(path).node) === FS.cwd()) {\n\t\t\tFS.chdir(joinPaths(FS.cwd(), '..'));\n\t\t}\n\t\tFS.rmdir(path);\n\t}\n\n\t/**\n\t * Lists the files and directories in the given directory.\n\t *\n\t * @param FS\n\t * @param path - The directory path to list.\n\t * @param options - Options for the listing.\n\t * @returns The list of files and directories in the given directory.\n\t */\n\tstatic listFiles(\n\t\tFS: Emscripten.RootFS,\n\t\tpath: string,\n\t\toptions: ListFilesOptions = { prependPath: false }\n\t): string[] {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn [];\n\t\t}\n\t\ttry {\n\t\t\tconst files = FS.readdir(path).filter(\n\t\t\t\t(name: string) => name !== '.' && name !== '..'\n\t\t\t);\n\t\t\tif (options.prependPath) {\n\t\t\t\tconst prepend = path.replace(/\\/$/, '');\n\t\t\t\treturn files.map((name: string) => `${prepend}/${name}`);\n\t\t\t}\n\t\t\treturn files;\n\t\t} catch (e) {\n\t\t\tlogger.error(e, { path });\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a directory exists in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path – The path to check.\n\t * @returns True if the path is a directory, false otherwise.\n\t */\n\tstatic isDir(FS: Emscripten.RootFS, path: string): boolean {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn FS.isDir(FS.lookupPath(path, { follow: true }).node.mode);\n\t}\n\n\t/**\n\t * Checks if a file exists in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path – The path to check.\n\t * @returns True if the path is a file, false otherwise.\n\t */\n\tstatic isFile(FS: Emscripten.RootFS, path: string): boolean {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn FS.isFile(FS.lookupPath(path, { follow: true }).node.mode);\n\t}\n\n\t/**\n\t * Creates a symlink in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param target\n\t * @param link\n\t */\n\tstatic symlink(FS: Emscripten.RootFS, target: string, link: string): any {\n\t\treturn FS.symlink(target, link);\n\t}\n\n\t/**\n\t * Checks if a path is a symlink in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path\n\t * @returns True if the path is a symlink, false otherwise.\n\t */\n\tstatic isSymlink(FS: Emscripten.RootFS, path: string): boolean {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn FS.isLink(FS.lookupPath(path).node.mode);\n\t}\n\n\t/**\n\t * Reads the target of a symlink in the PHP filesystem.\n\t * @param FS\n\t * @param path\n\t * @returns The target of the symlink.\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the path is not a symlink.\n\t */\n\tstatic readlink(FS: Emscripten.RootFS, path: string): string {\n\t\treturn FS.readlink(path);\n\t}\n\n\t/**\n\t * Gets the real path of a file in the PHP filesystem.\n\t * @param FS\n\t * @param path\n\t *\n\t * @returns The real path of the file.\n\t */\n\tstatic realpath(FS: Emscripten.RootFS, path: string): string {\n\t\treturn FS.lookupPath(path, { follow: true }).path;\n\t}\n\n\t/**\n\t * Checks if a file (or a directory) exists in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path - The file path to check.\n\t * @returns True if the file exists, false otherwise.\n\t */\n\tstatic fileExists(FS: Emscripten.RootFS, path: string): boolean {\n\t\ttry {\n\t\t\tFS.lookupPath(path);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Recursively creates a directory with the given path in the PHP filesystem.\n\t * For example, if the path is `/root/php/data`, and `/root` already exists,\n\t * it will create the directories `/root/php` and `/root/php/data`.\n\t *\n\t * @param FS\n\t * @param path - The directory path to create.\n\t */\n\tstatic mkdir(FS: Emscripten.RootFS, path: string) {\n\t\tFS.mkdirTree(path);\n\t}\n\n\tstatic copyRecursive(\n\t\tFS: Emscripten.FileSystemInstance,\n\t\tfromPath: string,\n\t\ttoPath: string\n\t) {\n\t\tconst fromNode = FS.lookupPath(fromPath).node;\n\t\tif (FS.isDir(fromNode.mode)) {\n\t\t\tFS.mkdirTree(toPath);\n\t\t\tconst filenames = FS.readdir(fromPath).filter(\n\t\t\t\t(name: string) => name !== '.' && name !== '..'\n\t\t\t);\n\t\t\tfor (const filename of filenames) {\n\t\t\t\tFSHelpers.copyRecursive(\n\t\t\t\t\tFS,\n\t\t\t\t\tjoinPaths(fromPath, filename),\n\t\t\t\t\tjoinPaths(toPath, filename)\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (FS.isLink(fromNode.mode)) {\n\t\t\tFS.symlink(FS.readlink(fromPath), toPath);\n\t\t} else {\n\t\t\tFS.writeFile(toPath, FS.readFile(fromPath));\n\t\t}\n\t}\n}\n\n// Apply decorators manually until the decorator syntax is supported\n// by Node.js. We do this so we can take advantage of Node.js type stripping\n// in the meantime.\n// TODO: Inline these decorators once Node.js supports it.\nFSHelpers.readFileAsText = rethrowFileSystemError('Could not read \"{path}\"')(\n\tFSHelpers.readFileAsText\n);\nFSHelpers.readFileAsBuffer = rethrowFileSystemError('Could not read \"{path}\"')(\n\tFSHelpers.readFileAsBuffer\n);\nFSHelpers.writeFile = rethrowFileSystemError('Could not write to \"{path}\"')(\n\tFSHelpers.writeFile\n);\nFSHelpers.unlink = rethrowFileSystemError('Could not unlink \"{path}\"')(\n\tFSHelpers.unlink\n);\nFSHelpers.rmdir = rethrowFileSystemError('Could not remove directory \"{path}\"')(\n\tFSHelpers.rmdir\n);\nFSHelpers.listFiles = rethrowFileSystemError(\n\t'Could not list files in \"{path}\"'\n)(FSHelpers.listFiles);\nFSHelpers.isDir = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.isDir\n);\nFSHelpers.isFile = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.isFile\n);\nFSHelpers.realpath = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.realpath\n);\nFSHelpers.fileExists = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.fileExists\n);\nFSHelpers.mkdir = rethrowFileSystemError('Could not create directory \"{path}\"')(\n\tFSHelpers.mkdir\n);\nFSHelpers.copyRecursive = rethrowFileSystemError(\n\t'Could not copy files from \"{path}\"'\n)(FSHelpers.copyRecursive);\n","import type { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type { ListFilesOptions, RmDirOptions } from './fs-helpers';\nimport type { PHP } from './php';\nimport type { PHPRequestHandler } from './php-request-handler';\nimport type { PHPResponse, StreamedPHPResponse } from './php-response';\nimport type {\n\tMessageListener,\n\tPHPEvent,\n\tPHPRequest,\n\tPHPRunOptions,\n} from './universal-php';\n\nconst _private = new WeakMap<\n\tPHPWorker,\n\t{\n\t\trequestHandler?: PHPRequestHandler;\n\t\tphp?: PHP;\n\t\tmonitor?: EmscriptenDownloadMonitor;\n\t}\n>();\n\nexport type LimitedPHPApi = Pick<\n\tPHP,\n\t| 'request'\n\t| 'defineConstant'\n\t| 'mkdir'\n\t| 'mkdirTree'\n\t| 'readFileAsText'\n\t| 'readFileAsBuffer'\n\t| 'writeFile'\n\t| 'unlink'\n\t| 'mv'\n\t| 'rmdir'\n\t| 'listFiles'\n\t| 'isDir'\n\t| 'fileExists'\n\t| 'chdir'\n\t| 'run'\n\t| 'onMessage'\n> & {\n\tdocumentRoot: PHP['documentRoot'];\n\tabsoluteUrl: PHP['absoluteUrl'];\n\taddEventListener:\n\t\t| PHP['addEventListener']\n\t\t| ((event: string, listener: (event: any) => any) => void);\n\tremoveEventListener:\n\t\t| PHP['removeEventListener']\n\t\t| ((event: string, listener: (event: any) => any) => void);\n};\n\nexport type PHPWorkerEvent = PHPEvent | { type: string };\nexport type PHPWorkerEventListener = (event: PHPWorkerEvent) => void;\n/**\n * A PHP client that can be used to run PHP code in the browser.\n */\nexport class PHPWorker implements LimitedPHPApi, AsyncDisposable {\n\t/** @inheritDoc @php-wasm/universal!RequestHandler.absoluteUrl */\n\tabsoluteUrl = '';\n\t/** @inheritDoc @php-wasm/universal!RequestHandler.documentRoot */\n\tdocumentRoot = '';\n\n\tprivate chroot: string | null = null;\n\n\t#eventListeners: Map<string, Set<PHPWorkerEventListener>> = new Map();\n\n\tonMessageListeners: MessageListener[] = [];\n\t/** @inheritDoc */\n\tconstructor(\n\t\trequestHandler?: PHPRequestHandler,\n\t\tmonitor?: EmscriptenDownloadMonitor\n\t) {\n\t\t/**\n\t\t * Workaround for TypeScript limitation.\n\t\t * Declaring a private field using the EcmaScript syntax like this:\n\t\t *\n\t\t * #php: PHP\n\t\t *\n\t\t * Makes that field a part of the public API of the class. This means\n\t\t * you can no longer assign seemingly compatible objects:\n\t\t *\n\t\t * ```ts\n\t\t * class PrivateEcma {\n\t\t * #privateProp: string = '';\n\t\t * callback() { }\n\t\t * }\n\t\t * interface CompatibleInterface {\n\t\t * callback(): void;\n\t\t * }\n\t\t * const compatObj: CompatibleInterface = {} as any;\n\t\t * const tsObj: PrivateEcma = compatObj;\n\t\t * // Property '#privateProp' is missing in type 'CompatibleInterface' but\n\t\t * // required in type 'PrivateEcma'\n\t\t * ```\n\t\t */\n\t\t_private.set(this, {\n\t\t\tmonitor,\n\t\t});\n\t\tif (requestHandler) {\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\t\t}\n\t}\n\n\tpublic __internal_setRequestHandler(requestHandler: PHPRequestHandler) {\n\t\tthis.absoluteUrl = requestHandler.absoluteUrl;\n\t\tthis.documentRoot = requestHandler.documentRoot;\n\t\tthis.chroot = this.documentRoot;\n\t\t_private.set(this, {\n\t\t\t..._private.get(this),\n\t\t\trequestHandler,\n\t\t});\n\t}\n\n\t/**\n\t * @internal\n\t * @deprecated\n\t * Do not use this method directly in the code consuming\n\t * the web API. It will change or even be removed without\n\t * a warning.\n\t */\n\tprotected __internal_getPHP() {\n\t\treturn _private.get(this)!.php;\n\t}\n\n\t/**\n\t * @internal\n\t * @deprecated\n\t * Do not use this method directly in the code consuming\n\t * the web API. It will change or even be removed without\n\t * a warning.\n\t */\n\tprotected __internal_getRequestHandler() {\n\t\treturn _private.get(this)!.requestHandler;\n\t}\n\n\tasync setPrimaryPHP(php: PHP) {\n\t\t_private.set(this, {\n\t\t\t..._private.get(this)!,\n\t\t\tphp,\n\t\t});\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHPRequestHandler.pathToInternalUrl */\n\tpathToInternalUrl(path: string): string {\n\t\treturn _private.get(this)!.requestHandler!.pathToInternalUrl(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHPRequestHandler.internalUrlToPath */\n\tinternalUrlToPath(internalUrl: string): string {\n\t\treturn _private\n\t\t\t.get(this)!\n\t\t\t.requestHandler!.internalUrlToPath(internalUrl);\n\t}\n\n\t/**\n\t * The onDownloadProgress event listener.\n\t */\n\tasync onDownloadProgress(\n\t\tcallback: (progress: CustomEvent<ProgressEvent>) => void\n\t): Promise<void> {\n\t\treturn _private\n\t\t\t.get(this)!\n\t\t\t.monitor?.addEventListener('progress', callback as any);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHP.mv */\n\tasync mv(fromPath: string, toPath: string) {\n\t\treturn _private.get(this)!.php!.mv(fromPath, toPath);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHP.rmdir */\n\tasync rmdir(path: string, options?: RmDirOptions) {\n\t\treturn _private.get(this)!.php!.rmdir(path, options);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHPRequestHandler.request */\n\tasync request(request: PHPRequest): Promise<PHPResponse> {\n\t\tconst requestHandler = _private.get(this)!.requestHandler!;\n\t\treturn await requestHandler.request(request);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.run */\n\tasync run(request: PHPRunOptions): Promise<PHPResponse> {\n\t\tconst { php, reap } = await this.acquirePHPInstance();\n\t\ttry {\n\t\t\treturn await php.run(request);\n\t\t} finally {\n\t\t\treap();\n\t\t}\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.cli */\n\tasync cli(\n\t\targv: string[],\n\t\toptions?: { env?: Record<string, string> }\n\t): Promise<StreamedPHPResponse> {\n\t\tconst { php, reap } = await this.acquirePHPInstance();\n\t\tlet response: StreamedPHPResponse;\n\t\ttry {\n\t\t\tresponse = await php.cli(argv, options);\n\t\t} catch (error) {\n\t\t\treap();\n\t\t\tthrow error;\n\t\t}\n\t\t/**\n\t\t * Register the reap() callback to run asynchronously once\n\t\t * the response is finished.\n\t\t *\n\t\t * We don't await for response.finished here. It is a\n\t\t * `StreamedPHPResponse` instance and the caller may want\n\t\t * to start processing the streamed data immediately.\n\t\t */\n\t\tresponse.finished.finally(reap);\n\t\treturn response;\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.chdir */\n\tchdir(path: string): void {\n\t\t// Remember the new chroot for all PHP instances yet to be acquired.\n\t\tthis.chroot = path;\n\t\treturn _private.get(this)!.php!.chdir(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.chdir */\n\tcwd(): string {\n\t\treturn _private.get(this)!.php!.cwd();\n\t}\n\n\t/**\n\t * @returns A PHP instance with a consistent chroot.\n\t */\n\tprivate async acquirePHPInstance() {\n\t\tconst { php, reap } = await _private\n\t\t\t.get(this)!\n\t\t\t.requestHandler!.processManager.acquirePHPInstance();\n\t\tif (this.chroot !== null) {\n\t\t\tphp.chdir(this.chroot);\n\t\t}\n\t\tthis.registerWorkerListeners(php);\n\t\treturn { php, reap };\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.setSapiName */\n\tsetSapiName(newName: string): void {\n\t\t_private.get(this)!.php!.setSapiName(newName);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.mkdir */\n\tmkdir(path: string): void {\n\t\treturn _private.get(this)!.php!.mkdir(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.mkdirTree */\n\tmkdirTree(path: string): void {\n\t\treturn _private.get(this)!.php!.mkdirTree(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.readFileAsText */\n\treadFileAsText(path: string): string {\n\t\treturn _private.get(this)!.php!.readFileAsText(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.readFileAsBuffer */\n\treadFileAsBuffer(path: string): Uint8Array {\n\t\treturn _private.get(this)!.php!.readFileAsBuffer(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.writeFile */\n\twriteFile(path: string, data: string | Uint8Array): void {\n\t\treturn _private.get(this)!.php!.writeFile(path, data);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.unlink */\n\tunlink(path: string): void {\n\t\treturn _private.get(this)!.php!.unlink(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.listFiles */\n\tlistFiles(path: string, options?: ListFilesOptions): string[] {\n\t\treturn _private.get(this)!.php!.listFiles(path, options);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.isDir */\n\tisDir(path: string): boolean {\n\t\treturn _private.get(this)!.php!.isDir(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.isFile */\n\tisFile(path: string): boolean {\n\t\treturn _private.get(this)!.php!.isFile(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.fileExists */\n\tfileExists(path: string): boolean {\n\t\treturn _private.get(this)!.php!.fileExists(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.onMessage */\n\tonMessage(listener: MessageListener) {\n\t\tthis.onMessageListeners.push(listener);\n\t\treturn async () => {\n\t\t\tthis.onMessageListeners = this.onMessageListeners.filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t};\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.defineConstant */\n\tdefineConstant(key: string, value: string | boolean | number | null): void {\n\t\t_private.get(this)!.php!.defineConstant(key, value);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.addEventListener */\n\taddEventListener(\n\t\teventType: PHPWorkerEvent['type'],\n\t\tlistener: PHPWorkerEventListener\n\t): void {\n\t\tif (!this.#eventListeners.has(eventType)) {\n\t\t\tthis.#eventListeners.set(eventType, new Set());\n\t\t}\n\t\tthis.#eventListeners.get(eventType)!.add(listener);\n\t}\n\n\t/**\n\t * Removes an event listener for a PHP event.\n\t * @param eventType - The type of event to remove the listener from.\n\t * @param listener - The listener function to be removed.\n\t */\n\tremoveEventListener(\n\t\teventType: PHPWorkerEvent['type'],\n\t\tlistener: PHPWorkerEventListener\n\t) {\n\t\tthis.#eventListeners.get(eventType)?.delete(listener);\n\t}\n\n\tprotected dispatchEvent<Event extends PHPWorkerEvent>(event: Event) {\n\t\tconst listeners = this.#eventListeners.get(event.type);\n\t\tif (!listeners) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const listener of listeners) {\n\t\t\tlistener(event);\n\t\t}\n\t}\n\n\tprotected registerWorkerListeners(php: PHP) {\n\t\tphp.addEventListener('*', async (event) => {\n\t\t\tthis.dispatchEvent(event);\n\t\t});\n\t\tphp.onMessage(async (message) => {\n\t\t\tfor (const listener of this.onMessageListeners) {\n\t\t\t\tconst returnData = await listener(message);\n\t\t\t\tif (returnData) {\n\t\t\t\t\treturn returnData;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn '';\n\t\t});\n\t}\n\n\tasync [Symbol.asyncDispose]() {\n\t\tawait _private.get(this)!.requestHandler?.[Symbol.asyncDispose]();\n\t}\n}\n","/**\n * Check if the Emscripten-thrown error is an exit code 0 error.\n *\n * @param e The error to check\n * @returns True if the error appears to represent an exit code or status\n */\nexport function isExitCode(e: any): e is { status: number } {\n\tif (!(e instanceof Error)) {\n\t\treturn false;\n\t}\n\treturn e?.name === 'ExitStatus' && 'status' in e;\n}\n","import { logger } from '@php-wasm/logger';\nimport type { IncomingMessage, Server, ServerResponse } from 'http';\n\nconst RuntimeId = Symbol('RuntimeId');\nconst loadedRuntimes: Map<number, PHPRuntime> = new Map();\nlet lastRuntimeId = 0;\n\n/**\n * Loads the PHP runtime with the given arguments and data dependencies.\n *\n * This function handles the entire PHP initialization pipeline. In particular,\n * it:\n *\n * * Instantiates the Emscripten PHP module\n * * Wires it together with the data dependencies and loads them\n * * Ensures is all happens in a correct order\n * * Waits until the entire loading sequence is finished\n *\n * Basic usage:\n *\n * ```js\n * const phpLoaderModule = await getPHPLoaderModule(\"7.4\");\n * const php = await loadPHPRuntime( phpLoaderModule );\n * console.log(php.run(`<?php echo \"Hello, world!\"; `));\n * // { stdout: ArrayBuffer containing the string \"Hello, world!\", stderr: [''], exitCode: 0 }\n * ```\n *\n * **The PHP loader module:**\n *\n * In the basic usage example, `phpLoaderModule` is **not** a vanilla\n * Emscripten module. Instead, it's an ESM module that wraps the regular\n * Emscripten output and adds some extra functionality. It's generated by the\n * Dockerfile shipped with this repo. Here's the API it provides:\n *\n * ```js\n * // php.wasm size in bytes:\n * export const dependenciesTotalSize = 5644199;\n *\n * // php.wasm filename:\n * export const dependencyFilename = 'php.wasm';\n *\n * // Run Emscripten's generated module:\n * export default function(jsEnv, emscriptenModuleArgs) {}\n * ```\n *\n * **PHP Filesystem:**\n *\n * Once initialized, the PHP has its own filesystem separate from the project\n * files. It's provided by [Emscripten and uses its FS library](https://emscripten.org/docs/api_reference/Filesystem-API.html).\n *\n * The API exposed to you via the PHP class is succinct and abstracts\n * certain unintuitive parts of low-level filesystem interactions.\n *\n * Here's how to use it:\n *\n * ```js\n * // Recursively create a /var/www directory\n * php.mkdirTree('/var/www');\n *\n * console.log(php.fileExists('/var/www/file.txt'));\n * // false\n *\n * php.writeFile('/var/www/file.txt', 'Hello from the filesystem!');\n *\n * console.log(php.fileExists('/var/www/file.txt'));\n * // true\n *\n * console.log(php.readFile('/var/www/file.txt'));\n * // \"Hello from the filesystem!\n *\n * // Delete the file:\n * php.unlink('/var/www/file.txt');\n * ```\n *\n * For more details consult the PHP class directly.\n *\n * **Data dependencies:**\n *\n * Using existing PHP packages by manually recreating them file-by-file would\n * be quite inconvenient. Fortunately, Emscripten provides a \"data dependencies\"\n * feature.\n *\n * Data dependencies consist of a `dependency.data` file and a `dependency.js`\n * loader and can be packaged with the [file_packager.py tool](\n * https://emscripten.org/docs/porting/files/packaging_files.html#packaging-using-the-file-packager-tool).\n * This project requires wrapping the Emscripten-generated `dependency.js` file\n * in an ES module as follows:\n *\n * 1. Prepend `export default function(emscriptenPHPModule) {'; `\n * 2. Prepend `export const dependencyFilename = '<DATA FILE NAME>'; `\n * 3. Prepend `export const dependenciesTotalSize = <DATA FILE SIZE>;`\n * 4. Append `}`\n *\n * Be sure to use the `--export-name=\"emscriptenPHPModule\"` file_packager.py\n * option.\n *\n * You want the final output to look as follows:\n *\n * ```js\n * export const dependenciesTotalSize = 5644199;\n * export const dependencyFilename = 'dependency.data';\n * export default function(emscriptenPHPModule) {\n * // Emscripten-generated code:\n * var Module = typeof emscriptenPHPModule !== 'undefined' ? emscriptenPHPModule : {};\n * // ... the rest of it ...\n * }\n * ```\n *\n * Such a constructions enables loading the `dependency.js` as an ES Module\n * using `import(\"/dependency.js\")`.\n *\n * Once it's ready, you can load PHP and your data dependencies as follows:\n *\n * ```js\n * const [phpLoaderModule, wordPressLoaderModule] = await Promise.all([\n * getPHPLoaderModule(\"7.4\"),\n * import(\"/wp.js\")\n * ]);\n * const php = await loadPHPRuntime(phpLoaderModule, {}, [wordPressLoaderModule]);\n * ```\n *\n * @public\n * @param phpLoaderModule - The ESM-wrapped Emscripten module. Consult the Dockerfile for the build process.\n * @param options - The Emscripten module arguments, see https://emscripten.org/docs/api_reference/module.html#affecting-execution.\n * @returns Loaded runtime id.\n */\n\nexport async function loadPHPRuntime(\n\tphpLoaderModule: PHPLoaderModule,\n\t...options: EmscriptenOptions[]\n): Promise<number> {\n\tconst phpModuleArgs = Object.assign({}, ...options);\n\n\tconst [phpReady, resolvePHP, rejectPHP] = makePromise();\n\n\tconst PHPRuntime = phpLoaderModule.init(currentJsRuntime, {\n\t\tonAbort(reason) {\n\t\t\trejectPHP(reason);\n\t\t\t// This can happen after PHP has been initialized so\n\t\t\t// let's just log it.\n\t\t\tlogger.error(reason);\n\t\t},\n\t\tENV: {},\n\t\t// Emscripten sometimes prepends a '/' to the path, which\n\t\t// breaks vite dev mode. An identity `locateFile` function\n\t\t// fixes it.\n\t\tlocateFile: (path) => path,\n\t\t...phpModuleArgs,\n\t\tnoInitialRun: true,\n\t\tonRuntimeInitialized() {\n\t\t\tif (phpModuleArgs.onRuntimeInitialized) {\n\t\t\t\tphpModuleArgs.onRuntimeInitialized(PHPRuntime);\n\t\t\t}\n\t\t\tresolvePHP();\n\t\t},\n\t});\n\n\tawait phpReady;\n\n\tconst id = ++lastRuntimeId;\n\n\t// TODO: Ask @adamziel why this is here.\n\t// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- why is this here?\n\tPHPRuntime.FS;\n\tPHPRuntime.id = id;\n\tPHPRuntime.originalExit = PHPRuntime._exit;\n\n\tPHPRuntime._exit = function (code: number) {\n\t\tif (PHPRuntime.outboundNetworkProxyServer) {\n\t\t\tPHPRuntime.outboundNetworkProxyServer.close();\n\t\t\tPHPRuntime.outboundNetworkProxyServer.closeAllConnections();\n\t\t}\n\t\tloadedRuntimes.delete(id);\n\t\treturn PHPRuntime.originalExit(code);\n\t};\n\n\tPHPRuntime[RuntimeId] = id;\n\tloadedRuntimes.set(id, PHPRuntime);\n\treturn id;\n}\n\nexport type RuntimeType = 'NODE' | 'WEB' | 'WORKER';\n\ndeclare const self: WindowOrWorkerGlobalScope;\ndeclare const WorkerGlobalScope: object | undefined;\n\nexport type PHPRuntimeId = number;\n\nexport function getLoadedRuntime(id: PHPRuntimeId): PHPRuntime {\n\treturn loadedRuntimes.get(id);\n}\n\nexport const currentJsRuntime = (function () {\n\tif (typeof process !== 'undefined' && process.release?.name === 'node') {\n\t\treturn 'NODE';\n\t} else if (typeof window !== 'undefined') {\n\t\treturn 'WEB';\n\t} else if (\n\t\ttypeof WorkerGlobalScope !== 'undefined' &&\n\t\tself instanceof (WorkerGlobalScope as any)\n\t) {\n\t\treturn 'WORKER';\n\t} else {\n\t\treturn 'NODE';\n\t}\n})();\n\n/**\n * Creates and exposes Promise resolve/reject methods for later use.\n */\nconst makePromise = () => {\n\tconst methods: any = [];\n\n\tconst promise = new Promise((resolve, reject) => {\n\t\tmethods.push(resolve, reject);\n\t});\n\tmethods.unshift(promise);\n\n\treturn methods as [Promise<any>, (v?: any) => void, (e?: any) => void];\n};\n\nexport type PHPRuntime = any;\n\nexport type PHPLoaderModule = {\n\tdependencyFilename: string;\n\tdependenciesTotalSize: number;\n\tinit: (jsRuntime: string, options: EmscriptenOptions) => PHPRuntime;\n};\n\nexport type DataModule = {\n\tdependencyFilename: string;\n\tdependenciesTotalSize: number;\n\tdefault: (phpRuntime: PHPRuntime) => void;\n};\n\nexport type EmscriptenOptions = {\n\tonAbort?: (message: string) => void;\n\t/**\n\t * Set to true for debugging tricky WebAssembly errors.\n\t */\n\tdebug?: boolean;\n\tENV?: Record<string, string>;\n\tlocateFile?: (path: string) => string;\n\tnoInitialRun?: boolean;\n\tprint?: (message: string) => void;\n\tprintErr?: (message: string) => void;\n\tquit?: (status: number, toThrow: any) => void;\n\tonRuntimeInitialized?: (phpRuntime: PHPRuntime) => void;\n\tmonitorRunDependencies?: (left: number) => void;\n\tonMessage?: (listener: EmscriptenMessageListener) => void;\n\toutboundNetworkProxyServer?: Server<\n\t\ttypeof IncomingMessage,\n\t\ttypeof ServerResponse\n\t>;\n\tinstantiateWasm?: (\n\t\tinfo: WebAssembly.Imports,\n\t\treceiveInstance: (\n\t\t\tinstance: WebAssembly.Instance,\n\t\t\tmodule: WebAssembly.Module\n\t\t) => void\n\t) => void;\n} & Record<string, any>;\n\nexport type EmscriptenMessageListener = (type: string, data: string) => void;\n","/*\n * This type is used in Comlink.transferHandlers.set('PHPResponse', { ... })\n * so be sure to update that if you change this type.\n */\nexport interface PHPResponseData {\n\t/**\n\t * Response headers.\n\t */\n\treadonly headers: Record<string, string[]>;\n\n\t/**\n\t * Response body. Contains the output from `echo`,\n\t * `print`, inline HTML etc.\n\t */\n\treadonly bytes: Uint8Array;\n\n\t/**\n\t * Stderr contents, if any.\n\t */\n\treadonly errors: string;\n\n\t/**\n\t * The exit code of the script. `0` is a success, while\n\t * `1` and `2` indicate an error.\n\t */\n\treadonly exitCode: number;\n\n\t/**\n\t * Response HTTP status code, e.g. 200.\n\t */\n\treadonly httpStatusCode: number;\n}\n\nconst responseTexts: Record<number, string> = {\n\t500: 'Internal Server Error',\n\t502: 'Bad Gateway',\n\t404: 'Not Found',\n\t403: 'Forbidden',\n\t401: 'Unauthorized',\n\t400: 'Bad Request',\n\t301: 'Moved Permanently',\n\t302: 'Found',\n\t307: 'Temporary Redirect',\n\t308: 'Permanent Redirect',\n\t204: 'No Content',\n\t201: 'Created',\n\t200: 'OK',\n};\n\nexport class StreamedPHPResponse {\n\t/**\n\t * Response headers.\n\t */\n\tprivate readonly headersStream: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Response body. Contains the output from `echo`,\n\t * `print`, inline HTML etc.\n\t */\n\treadonly stdout: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Stderr contents, if any.\n\t */\n\treadonly stderr: ReadableStream<Uint8Array>;\n\n\t/**\n\t * The exit code of the script. `0` is a success, anything\n\t * else is an error.\n\t */\n\treadonly exitCode: Promise<number>;\n\n\tprivate parsedHeaders: Promise<{\n\t\theaders: Record<string, string[]>;\n\t\thttpStatusCode: number;\n\t}> | null = null;\n\n\tprivate cachedStdoutBytes: Promise<Uint8Array> | null = null;\n\tprivate cachedStderrText: Promise<string> | null = null;\n\n\tconstructor(\n\t\theaders: ReadableStream<Uint8Array>,\n\t\tstdout: ReadableStream<Uint8Array>,\n\t\tstderr: ReadableStream<Uint8Array>,\n\t\texitCode: Promise<number>\n\t) {\n\t\tthis.headersStream = headers;\n\t\tthis.stdout = stdout;\n\t\tthis.stderr = stderr;\n\t\tthis.exitCode = exitCode;\n\t}\n\n\t/**\n\t * True if the response is successful (HTTP status code 200-399),\n\t * false otherwise.\n\t */\n\tasync ok(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst statusCode = await this.httpStatusCode;\n\t\t\treturn statusCode >= 200 && statusCode < 400;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Resolves when the response has finished processing – either successfully or not.\n\t */\n\tget finished(): Promise<void> {\n\t\treturn Promise.allSettled([this.exitCode.finally(() => {})]).then(\n\t\t\t() => {}\n\t\t);\n\t}\n\n\t/**\n\t * Resolves once HTTP headers are available.\n\t */\n\tget headers(): Promise<Record<string, string[]>> {\n\t\treturn this.getParsedHeaders().then((headers) => headers.headers);\n\t}\n\n\t/**\n\t * Resolves once HTTP status code is available.\n\t */\n\tget httpStatusCode(): Promise<number> {\n\t\treturn this.getParsedHeaders()\n\t\t\t.then((headers) => headers.httpStatusCode)\n\t\t\t.then((result) => {\n\t\t\t\tif (result !== undefined) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\t// If exit code is 0 or not available yet, fall back to parsed headers\n\t\t\t\treturn this.getParsedHeaders().then(\n\t\t\t\t\t(headers) => headers.httpStatusCode,\n\t\t\t\t\t() => 200\n\t\t\t\t);\n\t\t\t})\n\t\t\t.catch(() => 500);\n\t}\n\n\t/**\n\t * Exposes the stdout bytes as they're produced by the PHP instance\n\t */\n\tget stdoutText(): Promise<string> {\n\t\treturn this.stdoutBytes.then((bytes) =>\n\t\t\tnew TextDecoder().decode(bytes)\n\t\t);\n\t}\n\n\t/**\n\t * Exposes the stdout bytes as they're produced by the PHP instance\n\t */\n\tget stdoutBytes(): Promise<Uint8Array> {\n\t\tif (!this.cachedStdoutBytes) {\n\t\t\tthis.cachedStdoutBytes = streamToBytes(this.stdout);\n\t\t}\n\t\treturn this.cachedStdoutBytes;\n\t}\n\n\t/**\n\t * Exposes the stderr bytes as they're produced by the PHP instance\n\t */\n\tget stderrText(): Promise<string> {\n\t\tif (!this.cachedStderrText) {\n\t\t\tthis.cachedStderrText = streamToText(this.stderr);\n\t\t}\n\t\treturn this.cachedStderrText;\n\t}\n\n\tprivate async getParsedHeaders() {\n\t\tif (!this.parsedHeaders) {\n\t\t\tthis.parsedHeaders = parseHeadersStream(this.headersStream);\n\t\t}\n\t\treturn await this.parsedHeaders;\n\t}\n}\n\nasync function parseHeadersStream(\n\theadersStream: ReadableStream<Uint8Array>\n): Promise<{\n\theaders: Record<string, string[]>;\n\thttpStatusCode: number;\n}> {\n\tconst headersText = await streamToText(headersStream);\n\tlet headersData;\n\ttry {\n\t\theadersData = JSON.parse(headersText);\n\t} catch {\n\t\treturn { headers: {}, httpStatusCode: 200 };\n\t}\n\tconst headers: PHPResponse['headers'] = {};\n\tfor (const line of headersData.headers) {\n\t\t// Skip invalid response headers and the last \"__terminator__\" line.\n\t\t// @TODO: Should we log a warning on an invalid header line?\n\t\t// What's the typical browser behavior when encountering such a line?\n\t\tif (!line.includes(': ')) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst colonIndex = line.indexOf(': ');\n\t\tconst headerName = line.substring(0, colonIndex).toLowerCase();\n\t\tconst headerValue = line.substring(colonIndex + 2);\n\t\tif (!(headerName in headers)) {\n\t\t\theaders[headerName] = [] as string[];\n\t\t}\n\t\theaders[headerName].push(headerValue);\n\t}\n\treturn {\n\t\theaders,\n\t\thttpStatusCode: headersData.status,\n\t};\n}\n\nasync function streamToText(\n\tstream: ReadableStream<Uint8Array>\n): Promise<string> {\n\tconst reader = (stream as ReadableStream<BufferSource>)\n\t\t.pipeThrough(new TextDecoderStream())\n\t\t.getReader();\n\tconst text: string[] = [];\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) {\n\t\t\treturn text.join('');\n\t\t}\n\t\tif (value) {\n\t\t\ttext.push(value);\n\t\t}\n\t}\n}\n\nasync function streamToBytes(\n\tstream: ReadableStream<Uint8Array>\n): Promise<Uint8Array> {\n\tconst reader = stream.getReader();\n\tconst chunks: Uint8Array[] = [];\n\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) {\n\t\t\tconst totalLength = chunks.reduce(\n\t\t\t\t(acc, chunk) => acc + chunk.byteLength,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst result = new Uint8Array(totalLength);\n\t\t\tlet offset = 0;\n\t\t\tfor (const chunk of chunks) {\n\t\t\t\tresult.set(chunk, offset);\n\t\t\t\toffset += chunk.byteLength;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\tif (value) {\n\t\t\tchunks.push(value);\n\t\t}\n\t}\n}\n\n/**\n * PHP response. Body is an `ArrayBuffer` because it can\n * contain binary data.\n *\n * This type is used in Comlink.transferHandlers.set('PHPResponse', \\{ ... \\})\n * so be sure to update that if you change this type.\n */\nexport class PHPResponse implements PHPResponseData {\n\t/** @inheritDoc */\n\treadonly headers: Record<string, string[]>;\n\n\t/** @inheritDoc */\n\treadonly bytes: Uint8Array;\n\n\t/** @inheritDoc */\n\treadonly errors: string;\n\n\t/** @inheritDoc */\n\treadonly exitCode: number;\n\n\t/** @inheritDoc */\n\treadonly httpStatusCode: number;\n\n\tconstructor(\n\t\thttpStatusCode: number,\n\t\theaders: Record<string, string[]>,\n\t\tbody: Uint8Array,\n\t\terrors = '',\n\t\texitCode = 0\n\t) {\n\t\tthis.httpStatusCode = httpStatusCode;\n\t\tthis.headers = headers;\n\t\tthis.bytes = body;\n\t\tthis.exitCode = exitCode;\n\t\tthis.errors = errors;\n\t}\n\n\tstatic forHttpCode(httpStatusCode: number, text = '') {\n\t\treturn new PHPResponse(\n\t\t\thttpStatusCode,\n\t\t\t{},\n\t\t\tnew TextEncoder().encode(\n\t\t\t\ttext || responseTexts[httpStatusCode] || ''\n\t\t\t)\n\t\t);\n\t}\n\n\tstatic fromRawData(data: PHPResponseData): PHPResponse {\n\t\treturn new PHPResponse(\n\t\t\tdata.httpStatusCode,\n\t\t\tdata.headers,\n\t\t\tdata.bytes,\n\t\t\tdata.errors,\n\t\t\tdata.exitCode\n\t\t);\n\t}\n\n\tstatic async fromStreamedResponse(\n\t\tstreamedResponse: StreamedPHPResponse\n\t): Promise<PHPResponse> {\n\t\tawait streamedResponse.finished;\n\t\treturn new PHPResponse(\n\t\t\tawait streamedResponse.httpStatusCode,\n\t\t\tawait streamedResponse.headers,\n\t\t\tawait streamedResponse.stdoutBytes,\n\t\t\tawait streamedResponse.stderrText,\n\t\t\tawait streamedResponse.exitCode\n\t\t);\n\t}\n\n\t/**\n\t * True if the response is successful (HTTP status code 200-399),\n\t * false otherwise.\n\t */\n\tok(): boolean {\n\t\treturn this.httpStatusCode >= 200 && this.httpStatusCode < 400;\n\t}\n\n\ttoRawData(): PHPResponseData {\n\t\treturn {\n\t\t\theaders: this.headers,\n\t\t\tbytes: this.bytes,\n\t\t\terrors: this.errors,\n\t\t\texitCode: this.exitCode,\n\t\t\thttpStatusCode: this.httpStatusCode,\n\t\t};\n\t}\n\n\t/**\n\t * Response body as JSON.\n\t */\n\tget json() {\n\t\treturn JSON.parse(this.text);\n\t}\n\n\t/**\n\t * Response body as text.\n\t */\n\tget text() {\n\t\treturn new TextDecoder().decode(this.bytes);\n\t}\n}\n","/*\n * Node.js Polyfill for ErrorEvent.\n */\n\nconst kError = Symbol('error');\nconst kMessage = Symbol('message');\n\ninterface ErrorEventOptions {\n\t/* The error that generated this event */\n\terror?: Error;\n\t/* The error message */\n\tmessage?: string;\n}\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent2 extends Event {\n\t[kError]: any;\n\t[kMessage]: any;\n\t/**\n\t * Create a new `ErrorEvent`.\n\t *\n\t * @param type The name of the event\n\t * @param options A dictionary object that allows for setting\n\t * attributes via object members of the same name.\n\t */\n\tconstructor(type: 'error', options: ErrorEventOptions = {}) {\n\t\tsuper(type);\n\n\t\tthis[kError] = options.error === undefined ? null : options.error;\n\t\tthis[kMessage] = options.message === undefined ? '' : options.message;\n\t}\n\n\tget error() {\n\t\treturn this[kError];\n\t}\n\n\tget message() {\n\t\treturn this[kMessage];\n\t}\n}\nObject.defineProperty(ErrorEvent2.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent2.prototype, 'message', { enumerable: true });\n\nexport const ErrorEvent =\n\ttypeof globalThis.ErrorEvent === 'function'\n\t\t? globalThis.ErrorEvent\n\t\t: ErrorEvent2;\n","import { ErrorEvent } from './error-event-polyfill';\nimport { isExitCode } from './is-exit-code';\nimport { logger } from '@php-wasm/logger';\n\ntype Runtime = {\n\twasmExports: Record<string, unknown>;\n\tlastAsyncifyStackSource?: Error;\n};\n\nexport class UnhandledRejectionsTarget extends EventTarget {\n\tlistenersCount = 0;\n\toverride addEventListener(\n\t\ttype: unknown,\n\t\tcallback: unknown,\n\t\toptions?: boolean | AddEventListenerOptions\n\t): void {\n\t\t++this.listenersCount;\n\t\tsuper.addEventListener(\n\t\t\ttype as string,\n\t\t\tcallback as EventListener,\n\t\t\toptions\n\t\t);\n\t}\n\toverride removeEventListener(\n\t\ttype: unknown,\n\t\tcallback: unknown,\n\t\toptions?: boolean | EventListenerOptions\n\t): void {\n\t\t--this.listenersCount;\n\t\tsuper.removeEventListener(\n\t\t\ttype as string,\n\t\t\tcallback as EventListener,\n\t\t\toptions\n\t\t);\n\t}\n\thasListeners() {\n\t\treturn this.listenersCount > 0;\n\t}\n}\n\n/**\n * Creates Asyncify errors listener.\n *\n * Emscripten turns Asyncify errors into unhandled rejections by\n * throwing them outside of the context of the original function call.\n *\n * With this listener, we can catch and rethrow them in a proper context,\n * or at least log them in a more readable way.\n *\n * @param runtime\n */\nexport function improveWASMErrorReporting(runtime: Runtime) {\n\tconst target = new UnhandledRejectionsTarget();\n\tfor (const key in runtime.wasmExports) {\n\t\tif (typeof runtime.wasmExports[key] == 'function') {\n\t\t\tconst original = runtime.wasmExports[key] as any;\n\t\t\truntime.wasmExports[key] = function (...args: any[]) {\n\t\t\t\ttry {\n\t\t\t\t\treturn original(...args);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (!(e instanceof Error)) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (runtime.lastAsyncifyStackSource) {\n\t\t\t\t\t\te.cause = runtime.lastAsyncifyStackSource;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst clearMessage = clarifyErrorMessage(\n\t\t\t\t\t\te,\n\t\t\t\t\t\truntime.lastAsyncifyStackSource?.stack\n\t\t\t\t\t);\n\n\t\t\t\t\tif (target.hasListeners()) {\n\t\t\t\t\t\te.message = clearMessage;\n\t\t\t\t\t\tconst event = new ErrorEvent('error', { error: e });\n\t\t\t\t\t\ttarget.dispatchEvent(event);\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!isExitCode(e) || e.status !== 0) {\n\t\t\t\t\t\tshowCriticalErrorBox(clearMessage);\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\treturn target;\n}\n\nlet functionsMaybeMissingFromAsyncify: string[] = [];\nexport function getFunctionsMaybeMissingFromAsyncify() {\n\treturn functionsMaybeMissingFromAsyncify;\n}\n\nexport function clarifyErrorMessage(\n\tcrypticError: Error,\n\tasyncifyStack?: string\n) {\n\tif (crypticError.message === 'unreachable') {\n\t\tlet betterMessage = UNREACHABLE_ERROR;\n\t\tif (!asyncifyStack) {\n\t\t\tbetterMessage +=\n\t\t\t\t`\\n\\nThis stack trace is lacking. For a better one initialize \\n` +\n\t\t\t\t`the PHP runtime with debug: true, e.g. loadNodeRuntime('8.1', { emscriptenOptions: { debug: true } }).\\n\\n`;\n\t\t}\n\n\t\t// Extract all the PHP functions from the entire error chain.\n\t\tconst uniqueFunctions = new Set<string>(\n\t\t\textractPHPFunctionsFromStack(asyncifyStack || '')\n\t\t);\n\t\tlet lastError = crypticError;\n\t\tdo {\n\t\t\tfor (const fn of extractPHPFunctionsFromStack(\n\t\t\t\tlastError.stack || ''\n\t\t\t)) {\n\t\t\t\tuniqueFunctions.add(fn);\n\t\t\t}\n\t\t\tlastError = lastError.cause as Error;\n\t\t} while (lastError);\n\t\tfunctionsMaybeMissingFromAsyncify = Array.from(uniqueFunctions);\n\n\t\tfor (const fn of uniqueFunctions) {\n\t\t\tbetterMessage += ` * ${fn}\\n`;\n\t\t}\n\n\t\tbetterMessage += `Original error message: ${crypticError.message}\\n`;\n\n\t\treturn betterMessage;\n\t}\n\treturn crypticError.message;\n}\n\nconst UNREACHABLE_ERROR = `\n\"unreachable\" WASM instruction executed.\n\nThe typical reason is a PHP function missing from the ASYNCIFY_ONLY\nlist when building PHP.wasm.\n\nYou will need to file a new issue in the WordPress Playground repository\nand paste this error message there:\n\nhttps://github.com/WordPress/wordpress-playground/issues/new\n\nIf you're a core developer, the typical fix is to:\n\n* Isolate a minimal reproduction of the error\n* Add a reproduction of the error to php-asyncify.spec.ts in the WordPress Playground repository\n* Run 'npm run fix-asyncify'\n* Commit the changes, push to the repo, release updated NPM packages\n\nBelow is a list of all the PHP functions found in the stack trace to\nhelp with the minimal reproduction. If they're all already listed in\nthe Dockerfile, you'll need to trigger this error again with long stack\ntraces enabled. In node.js, you can do it using the --stack-trace-limit=100\nCLI option: \\n\\n`;\n\n// ANSI escape codes for CLI colors and formats\nconst redBg = '\\x1b[41m';\nconst bold = '\\x1b[1m';\nconst reset = '\\x1b[0m';\nconst eol = '\\x1B[K';\n\nlet logged = false;\nexport function showCriticalErrorBox(message: string) {\n\tif (logged) {\n\t\treturn;\n\t}\n\tlogged = true;\n\tif (message?.trim().startsWith('Program terminated with exit')) {\n\t\treturn;\n\t}\n\tlogger.log(`${redBg}\\n${eol}\\n${bold} WASM ERROR${reset}${redBg}`);\n\tfor (const line of message.split('\\n')) {\n\t\tlogger.log(`${eol} ${line} `);\n\t}\n\tlogger.log(`${reset}`);\n}\n\nfunction extractPHPFunctionsFromStack(stack: string) {\n\ttry {\n\t\tconst names = stack\n\t\t\t.split('\\n')\n\t\t\t.slice(1)\n\t\t\t.map((line) => {\n\t\t\t\tconst parts = line.trim().substring('at '.length).split(' ');\n\t\t\t\treturn {\n\t\t\t\t\tfn: parts.length >= 2 ? parts[0] : '<unknown>',\n\t\t\t\t\tisWasm: line.includes('wasm:/'),\n\t\t\t\t};\n\t\t\t})\n\t\t\t.filter(\n\t\t\t\t({ fn, isWasm }) =>\n\t\t\t\t\tisWasm &&\n\t\t\t\t\t!fn.startsWith('dynCall_') &&\n\t\t\t\t\t!fn.startsWith('invoke_')\n\t\t\t)\n\t\t\t.map(({ fn }) => fn);\n\t\treturn Array.from(new Set(names));\n\t} catch {\n\t\treturn [];\n\t}\n}\n","import { logger } from '@php-wasm/logger';\nimport {\n\tSemaphore,\n\tbasename,\n\tcreateSpawnHandler,\n\tjoinPaths,\n} from '@php-wasm/util';\nimport type { Emscripten } from './emscripten-types';\nimport type { ListFilesOptions, RmDirOptions } from './fs-helpers';\nimport { FSHelpers } from './fs-helpers';\nimport { isExitCode } from './is-exit-code';\nimport type { PHPRuntimeId } from './load-php-runtime';\nimport { getLoadedRuntime } from './load-php-runtime';\nimport type { PHPRequestHandler } from './php-request-handler';\nimport { PHPResponse, StreamedPHPResponse } from './php-response';\nimport type {\n\tChildProcess,\n\tMessageListener,\n\tPHPEvent,\n\tPHPEventListener,\n\tPHPRequest,\n\tPHPRequestHeaders,\n\tPHPRunOptions,\n\tSpawnHandler,\n} from './universal-php';\nimport type { UnhandledRejectionsTarget } from './wasm-error-reporting';\nimport {\n\tgetFunctionsMaybeMissingFromAsyncify,\n\timproveWASMErrorReporting,\n} from './wasm-error-reporting';\n\nconst STRING = 'string';\nconst NUMBER = 'number';\n\nexport const __private__dont__use = Symbol('__private__dont__use');\n\ntype ErrorSource = 'request' | 'php-wasm';\nexport class PHPExecutionFailureError extends Error {\n\tresponse: PHPResponse;\n\tsource: ErrorSource;\n\n\tconstructor(message: string, response: PHPResponse, source: ErrorSource) {\n\t\tsuper(message);\n\t\tthis.response = response;\n\t\tthis.source = source;\n\t}\n}\n\nexport type UnmountFunction = (() => Promise<any>) | (() => any);\nexport type MountHandler = (\n\tphp: PHP,\n\tFS: Emscripten.RootFS,\n\tvfsMountPoint: string\n) => UnmountFunction | Promise<UnmountFunction>;\n\nexport const PHP_INI_PATH = '/internal/shared/php.ini';\nconst AUTO_PREPEND_SCRIPT = '/internal/shared/auto_prepend_file.php';\n\nexport const USE_OPCACHE = true;\nconst OPCACHE_FILE_FOLDER = '/internal/shared/opcache';\n\ntype MountObject = {\n\tmountHandler: MountHandler;\n\tunmount: () => Promise<any>;\n};\n\n/**\n * An environment-agnostic wrapper around the Emscripten PHP runtime\n * that universals the super low-level API and provides a more convenient\n * higher-level API.\n *\n * It exposes a minimal set of methods to run PHP scripts and to\n * interact with the PHP filesystem.\n */\nexport class PHP implements Disposable {\n\tprotected [__private__dont__use]: any;\n\t#sapiName?: string;\n\t#phpWasmInitCalled = false;\n\t#wasmErrorsTarget: UnhandledRejectionsTarget | null = null;\n\t#eventListeners: Map<string, Set<PHPEventListener>> = new Map([\n\t\t// Listen to all events\n\t\t['*', new Set()],\n\t]);\n\t#messageListeners: MessageListener[] = [];\n\t#mounts: Record<string, MountObject> = {};\n\t#rotationOptions: {\n\t\tenabled: boolean;\n\t\trecreateRuntime: () => Promise<number> | number;\n\t\tneedsRotating: boolean;\n\t\tmaxRequests: number;\n\t\trequestsMade: number;\n\t} = {\n\t\tenabled: false,\n\t\trecreateRuntime: () => 0,\n\t\tneedsRotating: false,\n\t\tmaxRequests: 400,\n\t\trequestsMade: 0,\n\t};\n\n\trequestHandler?: PHPRequestHandler;\n\n\t/**\n\t * An exclusive lock that prevent multiple requests from running at\n\t * the same time.\n\t */\n\tsemaphore: Semaphore;\n\n\t/**\n\t * Initializes a PHP runtime.\n\t *\n\t * @internal\n\t * @param PHPRuntime - Optional. PHP Runtime ID as initialized by loadPHPRuntime.\n\t * @param requestHandlerOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.\n\t */\n\tconstructor(PHPRuntimeId?: PHPRuntimeId) {\n\t\tthis.semaphore = new Semaphore({ concurrency: 1 });\n\t\tif (PHPRuntimeId !== undefined) {\n\t\t\tthis.initializeRuntime(PHPRuntimeId);\n\t\t}\n\t\t/**\n\t\t * Listen to PHP runtime crashes.\n\t\t *\n\t\t * Registering an actual event listener helps with testing. The\n\t\t * test cases can dispatch synthetic error events and confirm the\n\t\t * PHP runtime is properly rotated.\n\t\t */\n\t\tthis.addEventListener('request.error', (event: any) => {\n\t\t\tif (event.source === 'php-wasm') {\n\t\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t * Adds an event listener for a PHP event.\n\t * @param eventType - The type of event to listen for.\n\t * @param listener - The listener function to be called when the event is triggered.\n\t */\n\taddEventListener(\n\t\teventType: PHPEvent['type'] | '*',\n\t\tlistener: PHPEventListener\n\t) {\n\t\tif (!this.#eventListeners.has(eventType)) {\n\t\t\tthis.#eventListeners.set(eventType, new Set());\n\t\t}\n\t\tthis.#eventListeners.get(eventType)!.add(listener);\n\t}\n\n\t/**\n\t * Removes an event listener for a PHP event.\n\t * @param eventType - The type of event to remove the listener from.\n\t * @param listener - The listener function to be removed.\n\t */\n\tremoveEventListener(\n\t\teventType: PHPEvent['type'] | '*',\n\t\tlistener: PHPEventListener\n\t) {\n\t\tthis.#eventListeners.get(eventType)?.delete(listener);\n\t}\n\n\tdispatchEvent<Event extends PHPEvent>(event: Event) {\n\t\tconst listeners = [\n\t\t\t...(this.#eventListeners.get(event.type) || []),\n\t\t\t...(this.#eventListeners.get('*') || []),\n\t\t];\n\t\tif (!listeners) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const listener of listeners) {\n\t\t\tlistener(event);\n\t\t}\n\t}\n\n\t/**\n\t * Listens to message sent by the PHP code.\n\t *\n\t * To dispatch messages, call:\n\t *\n\t * post_message_to_js(string $data)\n\t *\n\t * Arguments:\n\t * $data (string) – Data to pass to JavaScript.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const php = await PHP.load('8.0');\n\t *\n\t * php.onMessage(\n\t * // The data is always passed as a string\n\t * function (data: string) {\n\t * // Let's decode and log the data:\n\t * console.log(JSON.parse(data));\n\t * }\n\t * );\n\t *\n\t * // Now that we have a listener in place, let's\n\t * // dispatch a message:\n\t * await php.run({\n\t * code: `<?php\n\t * post_message_to_js(\n\t * json_encode([\n\t * 'post_id' => '15',\n\t * 'post_title' => 'This is a blog post!'\n\t * ])\n\t * ));\n\t * `,\n\t * });\n\t * ```\n\t *\n\t * @param listener Callback function to handle the message.\n\t */\n\tonMessage(listener: MessageListener) {\n\t\tthis.#messageListeners.push(listener);\n\t\treturn async () => {\n\t\t\tthis.#messageListeners = this.#messageListeners.filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t};\n\t}\n\n\tasync setSpawnHandler(handler: SpawnHandler | string) {\n\t\tif (typeof handler === 'string') {\n\t\t\t// This workaround is needed because the\n\t\t\t// Comlink messaging library used by Playground\n\t\t\t// has a hard time serializing a composite\n\t\t\t// handler object.\n\t\t\t// @TODO: Don't eval text-based functions here. Instead\n\t\t\t// use a MessagePort to communicate with the\n\t\t\t//\t\t parent context.\n\t\t\t// Perhaps this library would be useful:\n\t\t\t// https://github.com/WebReflection/coincident/\n\t\t\thandler = createSpawnHandler(eval(handler));\n\t\t}\n\t\tthis[__private__dont__use].spawnProcess = handler;\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tget absoluteUrl() {\n\t\treturn this.requestHandler!.absoluteUrl;\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tget documentRoot() {\n\t\treturn this.requestHandler!.documentRoot;\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tpathToInternalUrl(path: string): string {\n\t\treturn this.requestHandler!.pathToInternalUrl(path);\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tinternalUrlToPath(internalUrl: string): string {\n\t\treturn this.requestHandler!.internalUrlToPath(internalUrl);\n\t}\n\n\tinitializeRuntime(runtimeId: PHPRuntimeId) {\n\t\tif (this[__private__dont__use]) {\n\t\t\tthrow new Error('PHP runtime already initialized.');\n\t\t}\n\t\tconst runtime = getLoadedRuntime(runtimeId);\n\t\tif (!runtime) {\n\t\t\tthrow new Error('Invalid PHP runtime id.');\n\t\t}\n\t\tthis[__private__dont__use] = runtime;\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_phpini_path',\n\t\t\tnull,\n\t\t\t['string'],\n\t\t\t[PHP_INI_PATH]\n\t\t);\n\n\t\tif (!this.fileExists(PHP_INI_PATH)) {\n\t\t\tconst opcacheConfig = USE_OPCACHE\n\t\t\t\t? [\n\t\t\t\t\t\t// OPCache\n\t\t\t\t\t\t'opcache.enable = 1',\n\t\t\t\t\t\t'opcache.enable_cli = 1',\n\t\t\t\t\t\t'opcache.jit = 0',\n\t\t\t\t\t\t'opcache.interned_strings_buffer = 8',\n\t\t\t\t\t\t'opcache.max_accelerated_files = 1000',\n\t\t\t\t\t\t'opcache.memory_consumption = 64',\n\t\t\t\t\t\t'opcache.max_wasted_percentage = 5',\n\t\t\t\t\t\t'opcache.file_cache = ' + OPCACHE_FILE_FOLDER,\n\t\t\t\t\t\t// Always enable the file cache.\n\t\t\t\t\t\t'opcache.file_cache_only = 1',\n\t\t\t\t\t\t'opcache.file_cache_consistency_checks = 1',\n\t\t\t\t ]\n\t\t\t\t: [];\n\n\t\t\t/*if (\n\t\t\t\tUSE_OPCACHE &&\n\t\t\t\t!(\n\t\t\t\t\truntime.phpVersion.major === 8 &&\n\t\t\t\t\truntime.phpVersion.minor === 4\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\t// Old versions of PHP are RAM hungry. By using the file cache, we can reduce\n\t\t\t\t// the RAM usage during the first caching.\n\t\t\t\topcacheConfig.push(\n\t\t\t\t\t'opcache.file_cache_only = 1',\n\t\t\t\t\t'opcache.file_cache_consistency_checks = 1'\n\t\t\t\t);\n\t\t\t}*/\n\n\t\t\tif (!this.fileExists(OPCACHE_FILE_FOLDER)) {\n\t\t\t\tthis.mkdir(OPCACHE_FILE_FOLDER);\n\t\t\t}\n\n\t\t\tthis.writeFile(\n\t\t\t\tPHP_INI_PATH,\n\t\t\t\t[\n\t\t\t\t\t'auto_prepend_file=' + AUTO_PREPEND_SCRIPT,\n\t\t\t\t\t'memory_limit=256M',\n\t\t\t\t\t'ignore_repeated_errors = 1',\n\t\t\t\t\t'error_reporting = E_ALL',\n\t\t\t\t\t'display_errors = 1',\n\t\t\t\t\t'html_errors = 1',\n\t\t\t\t\t'display_startup_errors = On',\n\t\t\t\t\t'log_errors = 1',\n\t\t\t\t\t'always_populate_raw_post_data = -1',\n\t\t\t\t\t'upload_max_filesize = 2000M',\n\t\t\t\t\t'post_max_size = 2000M',\n\t\t\t\t\t'allow_url_fopen = On',\n\t\t\t\t\t'allow_url_include = Off',\n\t\t\t\t\t'session.save_path = /home/web_user',\n\t\t\t\t\t'implicit_flush = 1',\n\t\t\t\t\t'output_buffering = 0',\n\t\t\t\t\t'max_execution_time = 0',\n\t\t\t\t\t'max_input_time = -1',\n\t\t\t\t\t...opcacheConfig,\n\t\t\t\t].join('\\n')\n\t\t\t);\n\t\t}\n\t\tif (!this.fileExists(AUTO_PREPEND_SCRIPT)) {\n\t\t\tthis.writeFile(\n\t\t\t\tAUTO_PREPEND_SCRIPT,\n\t\t\t\t`<?php\n\t\t\t\t// Define constants set via defineConstant() calls\n\t\t\t\tif(file_exists('/internal/shared/consts.json')) {\n\t\t\t\t\t$consts = json_decode(file_get_contents('/internal/shared/consts.json'), true);\n\t\t\t\t\tforeach ($consts as $const => $value) {\n\t\t\t\t\t\tif (!defined($const) && is_scalar($value)) {\n\t\t\t\t\t\t\tdefine($const, $value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Preload all the files from /internal/shared/preload\n\t\t\t\tforeach (glob('/internal/shared/preload/*.php') as $file) {\n\t\t\t\t\trequire_once $file;\n\t\t\t\t}\n\t\t\t\t`\n\t\t\t);\n\t\t}\n\n\t\truntime['onMessage'] = async (\n\t\t\tdata: string\n\t\t): Promise<string | Uint8Array> => {\n\t\t\tfor (const listener of this.#messageListeners) {\n\t\t\t\tconst returnData = await listener(data);\n\n\t\t\t\tif (returnData) {\n\t\t\t\t\treturn returnData;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn '';\n\t\t};\n\n\t\tthis.#wasmErrorsTarget = improveWASMErrorReporting(runtime);\n\t\tthis.dispatchEvent({\n\t\t\ttype: 'runtime.initialized',\n\t\t});\n\t}\n\n\t/** @inheritDoc */\n\tasync setSapiName(newName: string) {\n\t\tconst result = this[__private__dont__use].ccall(\n\t\t\t'wasm_set_sapi_name',\n\t\t\tNUMBER,\n\t\t\t[STRING],\n\t\t\t[newName]\n\t\t);\n\t\tif (result !== 0) {\n\t\t\tthrow new Error(\n\t\t\t\t'Could not set SAPI name. This can only be done before the PHP WASM module is initialized.' +\n\t\t\t\t\t'Did you already dispatch any requests?'\n\t\t\t);\n\t\t}\n\t\tthis.#sapiName = newName;\n\t}\n\n\t/**\n\t * Changes the current working directory in the PHP filesystem.\n\t * This is the directory that will be used as the base for relative paths.\n\t * For example, if the current working directory is `/root/php`, and the\n\t * path is `data`, the absolute path will be `/root/php/data`.\n\t *\n\t * @param path - The new working directory.\n\t */\n\tchdir(path: string) {\n\t\tthis[__private__dont__use].FS.chdir(path);\n\t}\n\n\t/**\n\t * Gets the current working directory in the PHP filesystem.\n\t *\n\t * @returns The current working directory.\n\t */\n\tcwd() {\n\t\treturn this[__private__dont__use].FS.cwd();\n\t}\n\n\t/**\n\t * Changes the permissions of a file or directory.\n\t * @param path - The path to the file or directory.\n\t * @param mode - The new permissions.\n\t */\n\tchmod(path: string, mode: number) {\n\t\tthis[__private__dont__use].FS.chmod(path, mode);\n\t}\n\n\t/**\n\t * Do not use. Use new PHPRequestHandler() instead.\n\t * @deprecated\n\t */\n\tasync request(request: PHPRequest): Promise<PHPResponse> {\n\t\tlogger.warn(\n\t\t\t'PHP.request() is deprecated. Please use new PHPRequestHandler() instead.'\n\t\t);\n\t\tif (!this.requestHandler) {\n\t\t\tthrow new Error('No request handler available.');\n\t\t}\n\t\treturn this.requestHandler.request(request);\n\t}\n\n\t/**\n\t * Runs PHP code.\n\t *\n\t * This low-level method directly interacts with the WebAssembly\n\t * PHP interpreter.\n\t *\n\t * Every time you call run(), it prepares the PHP\n\t * environment and:\n\t *\n\t * * Resets the internal PHP state\n\t * * Populates superglobals ($_SERVER, $_GET, etc.)\n\t * * Handles file uploads\n\t * * Populates input streams (stdin, argv, etc.)\n\t * * Sets the current working directory\n\t *\n\t * You can use run() in two primary modes:\n\t *\n\t * ### Code snippet mode\n\t *\n\t * In this mode, you pass a string containing PHP code to run.\n\t *\n\t * ```ts\n\t * const result = await php.run({\n\t * \tcode: `<?php echo \"Hello world!\";`\n\t * });\n\t * // result.text === \"Hello world!\"\n\t * ```\n\t *\n\t * In this mode, information like __DIR__ or __FILE__ isn't very\n\t * useful because the code is not associated with any file.\n\t *\n\t * Under the hood, the PHP snippet is passed to the `zend_eval_string`\n\t * C function.\n\t *\n\t * ### File mode\n\t *\n\t * In the file mode, you pass a scriptPath and PHP executes a file\n\t * found at a that path:\n\t *\n\t * ```ts\n\t * php.writeFile(\n\t * \t\"/www/index.php\",\n\t * \t`<?php echo \"Hello world!\";\"`\n\t * );\n\t * const result = await php.run({\n\t * \tscriptPath: \"/www/index.php\"\n\t * });\n\t * // result.text === \"Hello world!\"\n\t * ```\n\t *\n\t * In this mode, you can rely on path-related information like __DIR__\n\t * or __FILE__.\n\t *\n\t * Under the hood, the PHP file is executed with the `php_execute_script`\n\t * C function.\n\t *\n\t * The `run()` method cannot be used in conjunction with `cli()`.\n\t *\n\t * @example\n\t * ```js\n\t * const result = await php.run({\n\t * \tcode: `<?php\n\t * \t\t$fp = fopen('php://stderr', 'w');\n\t * \t\tfwrite($fp, \"Hello, world!\");\n\t * \t`\n\t * });\n\t * // result.errors === \"Hello, world!\"\n\t * ```\n\t *\n\t * @deprecated Use stream() instead.\n\t * @param request - PHP runtime options.\n\t */\n\tasync run(request: PHPRunOptions): Promise<PHPResponse> {\n\t\tconst streamedResponse = await this.runStream(request);\n\t\tconst syncResponse = await PHPResponse.fromStreamedResponse(\n\t\t\tstreamedResponse\n\t\t);\n\n\t\tif (syncResponse.exitCode !== 0) {\n\t\t\t// Legacy run() behavior: throw if PHP exited with a non-zero exit code.\n\t\t\t// It could be a WASM crash, but it could be a PHP userland error such\n\t\t\t// as \"Fatal error: Uncaught Error: Call to undefined function no_such_function()\".\n\t\t\t//\n\t\t\t// runStream() does not throw just because an exitCode is non-zero.\n\t\t\tthrow new PHPExecutionFailureError(\n\t\t\t\t`PHP.run() failed with exit code ${syncResponse.exitCode}. \\n\\n=== Stdout ===\\n ${syncResponse.text}\\n\\n=== Stderr ===\\n ${syncResponse.errors}`,\n\t\t\t\tsyncResponse,\n\t\t\t\t'request'\n\t\t\t) as PHPExecutionFailureError;\n\t\t}\n\n\t\treturn syncResponse;\n\t}\n\t/**\n\t * Runs PHP code and returns a StreamedPHPResponse object that can be used to\n\t * process the output incrementally.\n\t *\n\t * This low-level method directly interacts with the WebAssembly\n\t * PHP interpreter and provides streaming capabilities for processing\n\t * PHP output as it becomes available.\n\t *\n\t * Every time you call stream(), it prepares the PHP\n\t * environment and:\n\t *\n\t * * Resets the internal PHP state\n\t * * Populates superglobals ($_SERVER, $_GET, etc.)\n\t * * Handles file uploads\n\t * * Populates input streams (stdin, argv, etc.)\n\t * * Sets the current working directory\n\t *\n\t * You can use stream() in two primary modes:\n\t *\n\t * ### Code snippet mode\n\t *\n\t * In this mode, you pass a string containing PHP code to run.\n\t *\n\t * ```ts\n\t * const streamedResponse = await php.stream({\n\t * \tcode: `<?php echo \"Hello world!\";`\n\t * });\n\t * // Process output incrementally\n\t * for await (const chunk of streamedResponse.text) {\n\t * \tconsole.log(chunk);\n\t * }\n\t * ```\n\t *\n\t * In this mode, information like __DIR__ or __FILE__ isn't very\n\t * useful because the code is not associated with any file.\n\t *\n\t * Under the hood, the PHP snippet is passed to the `zend_eval_string`\n\t * C function.\n\t *\n\t * ### File mode\n\t *\n\t * In the file mode, you pass a scriptPath and PHP executes a file\n\t * found at that path:\n\t *\n\t * ```ts\n\t * php.writeFile(\n\t * \t\"/www/index.php\",\n\t * \t`<?php echo \"Hello world!\";\"`\n\t * );\n\t * const streamedResponse = await php.stream({\n\t * \tscriptPath: \"/www/index.php\"\n\t * });\n\t * // Process output incrementally\n\t * for await (const chunk of streamedResponse.text) {\n\t * \tconsole.log(chunk);\n\t * }\n\t * ```\n\t *\n\t * In this mode, you can rely on path-related information like __DIR__\n\t * or __FILE__.\n\t *\n\t * Under the hood, the PHP file is executed with the `php_execute_script`\n\t * C function.\n\t *\n\t * The `stream()` method cannot be used in conjunction with `cli()`.\n\t *\n\t * @example\n\t * ```js\n\t * const streamedResponse = await php.stream({\n\t * \tcode: `<?php\n\t * \t\tfor ($i = 0; $i < 5; $i++) {\n\t * \t\t\techo \"Line $i\\n\";\n\t * \t\t\tflush();\n\t * \t\t}\n\t * \t`\n\t * });\n\t *\n\t * // Process output as it becomes available\n\t * for await (const chunk of streamedResponse.text) {\n\t * \tconsole.log('Received:', chunk);\n\t * }\n\t *\n\t * // Get the final exit code\n\t * const exitCode = await streamedResponse.exitCode;\n\t * console.log('Exit code:', exitCode);\n\t * ```\n\t *\n\t * @see run() – a synchronous version of this method.\n\t * @param request - PHP runtime options.\n\t * @returns A StreamedPHPResponse object.\n\t */\n\tasync runStream(request: PHPRunOptions): Promise<StreamedPHPResponse> {\n\t\t/*\n\t\t * Prevent multiple requests from running at the same time.\n\t\t * For example, if a request is made to a PHP file that\n\t\t * requests another PHP file, the second request may\n\t\t * be dispatched before the first one is finished.\n\t\t */\n\t\tconst release = await this.semaphore.acquire();\n\t\tlet heapBodyPointer: number | undefined;\n\t\tconst streamedResponsePromise = this.#executeWithErrorHandling(\n\t\t\tasync () => {\n\t\t\t\tif (!this.#phpWasmInitCalled) {\n\t\t\t\t\tawait this[__private__dont__use].ccall(\n\t\t\t\t\t\t'php_wasm_init',\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t[],\n\t\t\t\t\t\t[],\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisAsync: true,\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tthis.#phpWasmInitCalled = true;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\trequest.scriptPath &&\n\t\t\t\t\t!this.fileExists(request.scriptPath)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The script path \"${request.scriptPath}\" does not exist.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.#setRelativeRequestUri(request.relativeUri || '');\n\t\t\t\tthis.#setRequestMethod(request.method || 'GET');\n\t\t\t\tconst requestHeaders = normalizeHeaders(request.headers || {});\n\t\t\t\tconst host = requestHeaders['host'] || 'example.com:443';\n\n\t\t\t\tconst port = this.#inferPortFromHostAndProtocol(\n\t\t\t\t\thost,\n\t\t\t\t\trequest.protocol || 'http'\n\t\t\t\t);\n\t\t\t\tthis.#setRequestHost(host);\n\t\t\t\tthis.#setRequestPort(port);\n\t\t\t\tthis.#setRequestHeaders(requestHeaders);\n\t\t\t\tif (request.body) {\n\t\t\t\t\theapBodyPointer = this.#setRequestBody(request.body);\n\t\t\t\t}\n\t\t\t\tif (typeof request.code === 'string') {\n\t\t\t\t\tthis.writeFile('/internal/eval.php', request.code);\n\t\t\t\t\tthis.#setScriptPath('/internal/eval.php');\n\t\t\t\t} else if (typeof request.scriptPath === 'string') {\n\t\t\t\t\tthis.#setScriptPath(request.scriptPath || '');\n\t\t\t\t} else {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'The request object must have either a `code` or a ' +\n\t\t\t\t\t\t\t'`scriptPath` property.'\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst $_SERVER = this.#prepareServerEntries(\n\t\t\t\t\trequest.$_SERVER,\n\t\t\t\t\trequestHeaders,\n\t\t\t\t\tport\n\t\t\t\t);\n\n\t\t\t\tfor (const key in $_SERVER) {\n\t\t\t\t\tthis.#setServerGlobalEntry(key, $_SERVER[key]);\n\t\t\t\t}\n\n\t\t\t\tconst env = request.env || {};\n\t\t\t\tfor (const key in env) {\n\t\t\t\t\tthis.#setEnv(key, env[key]);\n\t\t\t\t}\n\n\t\t\t\treturn await this[__private__dont__use].ccall(\n\t\t\t\t\t'wasm_sapi_handle_request',\n\t\t\t\t\tNUMBER,\n\t\t\t\t\t[],\n\t\t\t\t\t[],\n\t\t\t\t\t{ async: true }\n\t\t\t\t);\n\t\t\t}\n\t\t);\n\n\t\tconst cleanup = () => {\n\t\t\tif (heapBodyPointer) {\n\t\t\t\ttry {\n\t\t\t\t\tthis[__private__dont__use].free(heapBodyPointer);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlogger.error(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Release the \"request in progress\" semaphore.\n\t\t\trelease();\n\n\t\t\t/**\n\t\t\t * Notify the filesystem journal (and any other listeners) that the request has ended.\n\t\t\t */\n\t\t\tthis.dispatchEvent({\n\t\t\t\ttype: 'request.end',\n\t\t\t});\n\t\t};\n\n\t\t// Free up resources once the request is fully handled.\n\t\treturn streamedResponsePromise.then(\n\t\t\t(streamedResponse) => {\n\t\t\t\tstreamedResponse.finished.finally(cleanup);\n\t\t\t\treturn streamedResponse;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\ttry {\n\t\t\t\t\tcleanup();\n\t\t\t\t} catch {\n\t\t\t\t\t// ... do nothing, just rethrow the original error in the finally section belos ...\n\t\t\t\t} finally {\n\t\t\t\t\t// eslint-disable-next-line no-unsafe-finally\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Prepares the $_SERVER entries for the PHP runtime.\n\t *\n\t * @param defaults Default entries to include in $_SERVER.\n\t * @param headers HTTP headers to include in $_SERVER (as HTTP_ prefixed entries).\n\t * @param port HTTP port, used to determine infer $_SERVER['HTTPS'] value if none\n\t * was provided.\n\t * @returns Computed $_SERVER entries.\n\t */\n\t#prepareServerEntries(\n\t\tdefaults: Record<string, string> | undefined,\n\t\theaders: PHPRequestHeaders,\n\t\tport: number\n\t): Record<string, string> {\n\t\tconst $_SERVER = {\n\t\t\t...(defaults || {}),\n\t\t};\n\t\t$_SERVER['HTTPS'] = $_SERVER['HTTPS'] || port === 443 ? 'on' : 'off';\n\t\tfor (const name in headers) {\n\t\t\tlet HTTP_prefix = 'HTTP_';\n\t\t\t/**\n\t\t\t * Some headers are special and don't have the HTTP_ prefix.\n\t\t\t */\n\t\t\tif (\n\t\t\t\t['content-type', 'content-length'].includes(name.toLowerCase())\n\t\t\t) {\n\t\t\t\tHTTP_prefix = '';\n\t\t\t}\n\t\t\t$_SERVER[`${HTTP_prefix}${name.toUpperCase().replace(/-/g, '_')}`] =\n\t\t\t\theaders[name];\n\t\t}\n\t\treturn $_SERVER;\n\t}\n\n\t#setRelativeRequestUri(uri: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_uri',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[uri]\n\t\t);\n\t\tlet queryString = '';\n\t\tif (uri.includes('?')) {\n\t\t\tqueryString = uri.substring(uri.indexOf('?') + 1);\n\t\t}\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_query_string',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[queryString]\n\t\t);\n\t}\n\n\t#setRequestHost(host: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_host',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[host]\n\t\t);\n\t}\n\n\t#setRequestPort(port: number) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_port',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[port]\n\t\t);\n\t}\n\n\t#inferPortFromHostAndProtocol(host: string, protocol: string) {\n\t\tlet port;\n\t\ttry {\n\t\t\tport = parseInt(new URL(host).port, 10);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\n\t\tif (!port || isNaN(port) || port === 80) {\n\t\t\tport = protocol === 'https' ? 443 : 80;\n\t\t}\n\t\treturn port;\n\t}\n\n\t#setRequestMethod(method: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_method',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[method]\n\t\t);\n\t}\n\n\t#setRequestHeaders(headers: PHPRequestHeaders) {\n\t\tif (headers['cookie']) {\n\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t'wasm_set_cookies',\n\t\t\t\tnull,\n\t\t\t\t[STRING],\n\t\t\t\t[headers['cookie']]\n\t\t\t);\n\t\t}\n\t\tif (headers['content-type']) {\n\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t'wasm_set_content_type',\n\t\t\t\tnull,\n\t\t\t\t[STRING],\n\t\t\t\t[headers['content-type']]\n\t\t\t);\n\t\t}\n\t\tif (headers['content-length']) {\n\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t'wasm_set_content_length',\n\t\t\t\tnull,\n\t\t\t\t[NUMBER],\n\t\t\t\t[parseInt(headers['content-length'], 10)]\n\t\t\t);\n\t\t}\n\t}\n\n\t#setRequestBody(body: string | Uint8Array) {\n\t\tlet size, contentLength;\n\t\tif (typeof body === 'string') {\n\t\t\tlogger.warn(\n\t\t\t\t'Passing a string as the request body is deprecated. Please use a Uint8Array instead. See ' +\n\t\t\t\t\t'https://github.com/WordPress/wordpress-playground/issues/997 for more details'\n\t\t\t);\n\t\t\tcontentLength = this[__private__dont__use].lengthBytesUTF8(body);\n\t\t\tsize = contentLength + 1;\n\t\t} else {\n\t\t\tcontentLength = body.byteLength;\n\t\t\tsize = body.byteLength;\n\t\t}\n\n\t\tconst heapBodyPointer = this[__private__dont__use].malloc(size);\n\t\tif (!heapBodyPointer) {\n\t\t\tthrow new Error('Could not allocate memory for the request body.');\n\t\t}\n\n\t\t// Write the string to the WASM memory\n\t\tif (typeof body === 'string') {\n\t\t\tthis[__private__dont__use].stringToUTF8(\n\t\t\t\tbody,\n\t\t\t\theapBodyPointer,\n\t\t\t\tsize + 1\n\t\t\t);\n\t\t} else {\n\t\t\tthis[__private__dont__use].HEAPU8.set(body, heapBodyPointer);\n\t\t}\n\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_body',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[heapBodyPointer]\n\t\t);\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_content_length',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[contentLength]\n\t\t);\n\t\treturn heapBodyPointer;\n\t}\n\n\t#setScriptPath(path: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_path_translated',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[path]\n\t\t);\n\t}\n\n\t#setServerGlobalEntry(key: string, value: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_add_SERVER_entry',\n\t\t\tnull,\n\t\t\t[STRING, STRING],\n\t\t\t[key, value]\n\t\t);\n\t}\n\n\t#setEnv(name: string, value: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_add_ENV_entry',\n\t\t\tnull,\n\t\t\t[STRING, STRING],\n\t\t\t[name, value]\n\t\t);\n\t}\n\n\t/**\n\t * Defines a constant in the PHP runtime.\n\t * @param key - The name of the constant.\n\t * @param value - The value of the constant.\n\t */\n\tdefineConstant(key: string, value: string | boolean | number | null) {\n\t\tlet consts = {};\n\t\ttry {\n\t\t\tconsts = JSON.parse(\n\t\t\t\tthis.fileExists('/internal/shared/consts.json')\n\t\t\t\t\t? this.readFileAsText('/internal/shared/consts.json') ||\n\t\t\t\t\t\t\t'{}'\n\t\t\t\t\t: '{}'\n\t\t\t);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t\tthis.writeFile(\n\t\t\t'/internal/shared/consts.json',\n\t\t\tJSON.stringify({\n\t\t\t\t...consts,\n\t\t\t\t[key]: value,\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Executes a PHP runtime function with proper error handling and streaming setup.\n\t * Sets up streaming infrastructure and returns a StreamedPHPResponse.\n\t *\n\t * @param executionFn - Function that returns the exit code or a promise of exit code\n\t * @returns Promise that resolves to a StreamedPHPResponse\n\t */\n\tasync #executeWithErrorHandling(\n\t\texecutionFn: () => any\n\t): Promise<StreamedPHPResponse> {\n\t\tif (\n\t\t\tthis.#rotationOptions.enabled &&\n\t\t\tthis.#rotationOptions.needsRotating\n\t\t) {\n\t\t\tawait this.rotateRuntime();\n\t\t}\n\t\t++this.#rotationOptions.requestsMade;\n\t\tif (\n\t\t\tthis.#rotationOptions.requestsMade >=\n\t\t\tthis.#rotationOptions.maxRequests\n\t\t) {\n\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t}\n\n\t\tconst emscriptenModule = this[__private__dont__use];\n\n\t\tconst headers = await createInvertedReadableStream<Uint8Array>();\n\t\temscriptenModule.onHeaders = (chunk: Uint8Array) => {\n\t\t\tif (streamsClosed || headersClosed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// slice() chunk to clone the data and preserve it for the reader later on.\n\t\t\t// We need that because the ArrayBuffer underlying `chunk` may change\n\t\t\t// after this callback return. Without cloning, the reader would read\n\t\t\t// whatever bytes are available in the ArrayBuffer at the time of the read.\n\t\t\theaders.controller.enqueue(chunk.slice());\n\t\t};\n\t\tlet headersClosed = false;\n\t\tconst closeHeadersStream = () => {\n\t\t\tif (!headersClosed) {\n\t\t\t\theadersClosed = true;\n\t\t\t\theaders.controller.close();\n\t\t\t}\n\t\t};\n\n\t\tconst stdout = await createInvertedReadableStream<Uint8Array>();\n\t\temscriptenModule.onStdout = (chunk: Uint8Array) => {\n\t\t\tcloseHeadersStream();\n\t\t\tif (streamsClosed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstdout.controller.enqueue(chunk.slice());\n\t\t};\n\n\t\tconst stderr = await createInvertedReadableStream<Uint8Array>();\n\t\temscriptenModule.onStderr = (chunk: Uint8Array) => {\n\t\t\tif (streamsClosed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstderr.controller.enqueue(chunk.slice());\n\t\t};\n\n\t\tlet streamsClosed = false;\n\n\t\tlet errorListener: any;\n\n\t\tconst runExecutionFunction = async () => {\n\t\t\ttry {\n\t\t\t\t/*\n\t\t\t\t * Emscripten throws WASM failures outside of the promise chain so we need\n\t\t\t\t * to listen for them here and rethrow in the correct context. Otherwise we\n\t\t\t\t * get crashes and unhandled promise rejections without any useful error\n\t\t\t\t * messages or meaningful stack traces.\n\t\t\t\t */\n\t\t\t\tconst exitCode = await Promise.race([\n\t\t\t\t\texecutionFn(),\n\t\t\t\t\tnew Promise((_, reject) => {\n\t\t\t\t\t\terrorListener = (e: ErrorEvent) => {\n\t\t\t\t\t\t\tif (!isExitCode(e.error)) {\n\t\t\t\t\t\t\t\treject(e.error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tthis.#wasmErrorsTarget?.addEventListener(\n\t\t\t\t\t\t\t'error',\n\t\t\t\t\t\t\terrorListener,\n\t\t\t\t\t\t\t{ once: true }\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t\treturn exitCode;\n\t\t\t} catch (e) {\n\t\t\t\t/**\n\t\t\t\t * Emscripten sometimes communicates program exit as an error. Let's\n\t\t\t\t * turn exit code errors into integers again.\n\t\t\t\t */\n\t\t\t\tif (isExitCode(e)) {\n\t\t\t\t\treturn e.status;\n\t\t\t\t}\n\n\t\t\t\t// Non-exit-code errors indicate a WASM runtime crash. Let's clean up and throw.\n\t\t\t\tstdout.controller.error(e);\n\t\t\t\tstderr.controller.error(e);\n\t\t\t\theaders.controller.error(e);\n\t\t\t\tstreamsClosed = true;\n\n\t\t\t\t/**\n\t\t\t\t * A non-exit-code error means an irrecoverable crash. Let's make\n\t\t\t\t * it very clear to the consumers of this API – every method\n\t\t\t\t * call on this PHP instance will throw an error from now on.\n\t\t\t\t */\n\t\t\t\tfor (const name in this) {\n\t\t\t\t\tif (typeof this[name] === 'function') {\n\t\t\t\t\t\t(this as any)[name] = () => {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`PHP runtime has crashed – see the earlier error for details.`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t(this as any).functionsMaybeMissingFromAsyncify =\n\t\t\t\t\tgetFunctionsMaybeMissingFromAsyncify();\n\n\t\t\t\tthrow e;\n\t\t\t} finally {\n\t\t\t\tif (!streamsClosed) {\n\t\t\t\t\tstdout.controller.close();\n\t\t\t\t\tstderr.controller.close();\n\t\t\t\t\tcloseHeadersStream();\n\t\t\t\t\tstreamsClosed = true;\n\t\t\t\t}\n\t\t\t\tthis.#wasmErrorsTarget?.removeEventListener(\n\t\t\t\t\t'error',\n\t\t\t\t\terrorListener\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\t/**\n\t\t * Dispatch a request.error event for any global crash handlers. For example,\n\t\t * Playground web uses this to automatically display a \"Report crash\" modal.\n\t\t */\n\t\tconst exitCodePromise = runExecutionFunction().then(\n\t\t\t(exitCode) => {\n\t\t\t\t/**\n\t\t\t\t * Emit errors related to PHP script failures (exit code other than 0)\n\t\t\t\t */\n\t\t\t\tif (exitCode !== 0) {\n\t\t\t\t\tthis.dispatchEvent({\n\t\t\t\t\t\ttype: 'request.error',\n\t\t\t\t\t\terror: new Error(\n\t\t\t\t\t\t\t`PHP.run() failed with exit code ${exitCode}.`\n\t\t\t\t\t\t),\n\t\t\t\t\t\t// Distinguish between PHP request and PHP-wasm errors\n\t\t\t\t\t\tsource: 'php-wasm',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn exitCode;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\t/**\n\t\t\t\t * Emit all other errors.\n\t\t\t\t */\n\t\t\t\t// Distinguish between PHP request and PHP-wasm errors\n\t\t\t\tconst source = (error as any).source ?? 'php-wasm';\n\t\t\t\tthis.dispatchEvent({\n\t\t\t\t\ttype: 'request.error',\n\t\t\t\t\terror: error as any as Error,\n\t\t\t\t\tsource,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t);\n\n\t\treturn new StreamedPHPResponse(\n\t\t\theaders.stream,\n\t\t\tstdout.stream,\n\t\t\tstderr.stream,\n\t\t\texitCodePromise\n\t\t);\n\t}\n\n\t/**\n\t * Recursively creates a directory with the given path in the PHP filesystem.\n\t * For example, if the path is `/root/php/data`, and `/root` already exists,\n\t * it will create the directories `/root/php` and `/root/php/data`.\n\t *\n\t * @param path - The directory path to create.\n\t */\n\tmkdir(path: string) {\n\t\tconst result = FSHelpers.mkdir(this[__private__dont__use].FS, path);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * @deprecated Use mkdir instead.\n\t */\n\tmkdirTree(path: string) {\n\t\treturn FSHelpers.mkdir(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as a string.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\treadFileAsText(path: string) {\n\t\treturn FSHelpers.readFileAsText(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as an array buffer.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\treadFileAsBuffer(path: string): Uint8Array {\n\t\treturn FSHelpers.readFileAsBuffer(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Overwrites data in a file in the PHP filesystem.\n\t * Creates a new file if one doesn't exist yet.\n\t *\n\t * @param path - The file path to write to.\n\t * @param data - The data to write to the file.\n\t */\n\twriteFile(path: string, data: string | Uint8Array) {\n\t\tconst result = FSHelpers.writeFile(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tpath,\n\t\t\tdata\n\t\t);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Removes a file from the PHP filesystem.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param path - The file path to remove.\n\t */\n\tunlink(path: string) {\n\t\tconst result = FSHelpers.unlink(this[__private__dont__use].FS, path);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Moves a file or directory in the PHP filesystem to a\n\t * new location.\n\t *\n\t * @param oldPath The path to rename.\n\t * @param newPath The new path.\n\t */\n\tmv(fromPath: string, toPath: string) {\n\t\tconst result = FSHelpers.mv(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tfromPath,\n\t\t\ttoPath\n\t\t);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Removes a directory from the PHP filesystem.\n\t *\n\t * @param path The directory path to remove.\n\t * @param options Options for the removal.\n\t */\n\trmdir(path: string, options: RmDirOptions = { recursive: true }) {\n\t\tconst result = FSHelpers.rmdir(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tpath,\n\t\t\toptions\n\t\t);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Lists the files and directories in the given directory.\n\t *\n\t * @param path - The directory path to list.\n\t * @param options - Options for the listing.\n\t * @returns The list of files and directories in the given directory.\n\t */\n\tlistFiles(\n\t\tpath: string,\n\t\toptions: ListFilesOptions = { prependPath: false }\n\t) {\n\t\treturn FSHelpers.listFiles(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tpath,\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Checks if a directory exists in the PHP filesystem.\n\t *\n\t * @param path – The path to check.\n\t * @returns True if the path is a directory, false otherwise.\n\t */\n\tisDir(path: string) {\n\t\treturn FSHelpers.isDir(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Checks if a file exists in the PHP filesystem.\n\t *\n\t * @param path – The path to check.\n\t * @returns True if the path is a file, false otherwise.\n\t */\n\tisFile(path: string) {\n\t\treturn FSHelpers.isFile(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Creates a symlink in the PHP filesystem.\n\t * @param target\n\t * @param path\n\t */\n\tsymlink(target: string, path: string) {\n\t\treturn FSHelpers.symlink(this[__private__dont__use].FS, target, path);\n\t}\n\n\t/**\n\t * Checks if a path is a symlink in the PHP filesystem.\n\t *\n\t * @param path\n\t * @returns True if the path is a symlink, false otherwise.\n\t */\n\tisSymlink(path: string) {\n\t\treturn FSHelpers.isSymlink(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Reads the target of a symlink in the PHP filesystem.\n\t *\n\t * @param path\n\t * @returns The target of the symlink.\n\t */\n\treadlink(path: string) {\n\t\treturn FSHelpers.readlink(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Resolves the real path of a file in the PHP filesystem.\n\t * @param path\n\t * @returns The real path of the file.\n\t */\n\trealpath(path: string) {\n\t\treturn FSHelpers.realpath(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Checks if a file (or a directory) exists in the PHP filesystem.\n\t *\n\t * @param path - The file path to check.\n\t * @returns True if the file exists, false otherwise.\n\t */\n\tfileExists(path: string) {\n\t\treturn FSHelpers.fileExists(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Enables inline PHP runtime rotation after a certain number of requests\n\t * or an internal crash.\n\t */\n\tenableRuntimeRotation(options: {\n\t\trecreateRuntime: () => Promise<number> | number;\n\t\tmaxRequests?: number;\n\t}) {\n\t\tthis.#rotationOptions = {\n\t\t\t...this.#rotationOptions,\n\t\t\tenabled: true,\n\t\t\trecreateRuntime: options.recreateRuntime,\n\t\t\tmaxRequests: options.maxRequests ?? 400,\n\t\t};\n\t}\n\n\tprivate async rotateRuntime() {\n\t\tif (!this.#rotationOptions.enabled) {\n\t\t\tthrow new Error(\n\t\t\t\t'Runtime rotation is not enabled. Call enableRuntimeRotation() first.'\n\t\t\t);\n\t\t}\n\t\tawait this.hotSwapPHPRuntime(\n\t\t\tawait this.#rotationOptions.recreateRuntime()\n\t\t);\n\t\tthis.#rotationOptions.requestsMade = 0;\n\t\tthis.#rotationOptions.needsRotating = false;\n\t}\n\n\t/**\n\t * Hot-swaps the PHP runtime for a new one without\n\t * interrupting the operations of this PHP instance.\n\t *\n\t * @param runtime\n\t */\n\tasync hotSwapPHPRuntime(runtime: number) {\n\t\t// Once we secure the lock and have the new runtime ready,\n\t\t// the rest of the swap handler is synchronous to make sure\n\t\t// no other operations acts on the old runtime or FS.\n\t\t// If there was await anywhere here, we'd risk applyng\n\t\t// asynchronous changes to either the filesystem or the\n\t\t// old PHP runtime without propagating them to the new\n\t\t// runtime.\n\n\t\tconst oldFS = this[__private__dont__use].FS;\n\t\tconst oldRootLevelPaths = this.listFiles('/').map((file) => `/${file}`);\n\t\tconst oldSpawnProcess = this[__private__dont__use].spawnProcess;\n\n\t\t// Temporarily set CWD to / and restore it at the end of this method.\n\t\t//\n\t\t// There's a chance cleaning up old mounts via mount.unmount()\n\t\t// will attempt removing the CWD. Normally, this would throw\n\t\t// FS.ErrnoError(10) EBUSY and interrupt the PHP runtime rotation,\n\t\t// leaving us in a broken state.\n\t\t//\n\t\t// Even though removing the CWD directory is not allowed by the\n\t\t// filesystem, we don't care that much here – we're merely freeing\n\t\t// all the resources allocated by the old filesystem before it's\n\t\t// garbage collected. We are about to recreate the same filesystem\n\t\t// structure and mounts in another PHP runtime.\n\t\t//\n\t\t// Therefore, let's suspend the strict EBUSY check by setting the CWD\n\t\t// to / for the cleanup purposes. We'll attempt to restore the original\n\t\t// CWD on the new runtime once we re-apply all the mounts there. We'll\n\t\t// only have a real reason to throw an error if the CWD path does not\n\t\t// exist in the new filesystem after the rotation.\n\t\tconst oldCWD = oldFS.cwd();\n\t\toldFS.chdir('/');\n\n\t\t// Remember mounts to apply to new runtime\n\t\tconst mountHandlersToReapplyInOrder = Object.entries(this.#mounts).map(\n\t\t\t([vfsPath, mount]) => ({\n\t\t\t\tmountHandler: mount.mountHandler,\n\t\t\t\tvfsPath,\n\t\t\t})\n\t\t);\n\n\t\t// Unmount all the mount handlers in reverse order because each nested\n\t\t// mount depends upon the parent mount which preceded it.\n\t\tconst mountsToUnmountInReverseOrder = Object.values(\n\t\t\tthis.#mounts\n\t\t).reverse();\n\t\tfor (const mount of mountsToUnmountInReverseOrder) {\n\t\t\tawait mount.unmount();\n\t\t}\n\n\t\t// Kill the current runtime\n\t\ttry {\n\t\t\tthis.exit();\n\t\t} catch {\n\t\t\t// Ignore the exit-related exception\n\t\t}\n\n\t\t// Initialize the new runtime\n\t\tthis.initializeRuntime(runtime);\n\n\t\tif (oldSpawnProcess) {\n\t\t\tthis[__private__dont__use].spawnProcess = oldSpawnProcess;\n\t\t}\n\n\t\tif (this.#sapiName) {\n\t\t\tthis.setSapiName(this.#sapiName);\n\t\t}\n\n\t\t/**\n\t\t * Ensure the new PHP instance has the same file structure as the old one.\n\t\t *\n\t\t * Catch: The underlying filesystems may be completely separate but they may be\n\t\t * partially shared via NODEFS or PROXYFS mounts. We need to be careful and only\n\t\t * recreate the MEMFS directories that aren't already shared – otherwise we'll\n\t\t * write data to shared paths that other, concurrent workers may be using.\n\t\t */\n\t\tconst newFs = this[__private__dont__use].FS;\n\t\tfor (const path of oldRootLevelPaths) {\n\t\t\t// The /request directory holds per-request state that is isolated to a\n\t\t\t// single PHP instance. Let's not copy it.\n\t\t\tif (path && path !== '/request') {\n\t\t\t\tcopyMEMFSNodes(oldFS, newFs, path);\n\t\t\t}\n\t\t}\n\n\t\t// Re-mount all the mount handlers in order\n\t\tfor (const { mountHandler, vfsPath } of mountHandlersToReapplyInOrder) {\n\t\t\tthis.mkdir(vfsPath);\n\t\t\tawait this.mount(vfsPath, mountHandler);\n\t\t}\n\t\ttry {\n\t\t\tnewFs.chdir(oldCWD);\n\t\t} catch (e) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to restore CWD to ${oldCWD} after PHP runtime rotation.`,\n\t\t\t\t{\n\t\t\t\t\tcause: e,\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Mounts a filesystem to a given path in the PHP filesystem.\n\t *\n\t * @param virtualFSPath - Where to mount it in the PHP virtual filesystem.\n\t * @param mountHandler - The mount handler to use.\n\t * @return Unmount function to unmount the filesystem.\n\t */\n\tasync mount(\n\t\tvirtualFSPath: string,\n\t\tmountHandler: MountHandler\n\t): Promise<UnmountFunction> {\n\t\tconst unmountCallback = await mountHandler(\n\t\t\tthis,\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tvirtualFSPath\n\t\t);\n\t\tconst mountObject = {\n\t\t\tmountHandler,\n\t\t\tunmount: async () => {\n\t\t\t\tawait unmountCallback();\n\t\t\t\tdelete this.#mounts[virtualFSPath];\n\t\t\t},\n\t\t};\n\t\tthis.#mounts[virtualFSPath] = mountObject;\n\t\treturn () => {\n\t\t\tmountObject.unmount();\n\t\t};\n\t}\n\n\t/**\n\t * Starts a PHP CLI session with given arguments.\n\t *\n\t * This method can only be used when PHP was compiled with the CLI SAPI\n\t * and it cannot be used in conjunction with `run()`.\n\t *\n\t * Once this method finishes running, the PHP instance is no\n\t * longer usable and should be discarded. This is because PHP\n\t * internally cleans up all the resources and calls exit().\n\t *\n\t * @param argv - The arguments to pass to the CLI.\n\t * @returns The exit code of the CLI session.\n\t */\n\tasync cli(\n\t\targv: string[],\n\t\toptions: { env?: Record<string, string>; cwd?: string } = {}\n\t): Promise<StreamedPHPResponse> {\n\t\tif (basename(argv[0] ?? '') !== 'php') {\n\t\t\treturn this.subProcess(argv, options);\n\t\t}\n\n\t\tif (this.#phpWasmInitCalled) {\n\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t}\n\n\t\tconst release = await this.semaphore.acquire();\n\n\t\treturn await this.#executeWithErrorHandling(() => {\n\t\t\tconst env = options.env || {};\n\t\t\tfor (const [key, value] of Object.entries(env)) {\n\t\t\t\tthis.#setEnv(key, value);\n\t\t\t}\n\t\t\t// Enforce the use of the internal php.ini file.\n\t\t\targv = [argv[0], '-c', PHP_INI_PATH, ...argv.slice(1)];\n\t\t\tfor (const arg of argv) {\n\t\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t\t'wasm_add_cli_arg',\n\t\t\t\t\tnull,\n\t\t\t\t\t[STRING],\n\t\t\t\t\t[arg]\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn this[__private__dont__use].ccall('run_cli', null, [], [], {\n\t\t\t\tasync: true,\n\t\t\t});\n\t\t})\n\t\t\t.then((response) => {\n\t\t\t\tresponse.exitCode.finally(release);\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t\t});\n\t}\n\n\t/**\n\t * Runs an arbitrary CLI command using the spawn handler associated\n\t * with this PHP instance.\n\t *\n\t * @param argv\n\t * @param options\n\t * @returns StreamedPHPResponse.\n\t */\n\tprivate async subProcess(\n\t\targv: string[],\n\t\toptions: { env?: Record<string, string>; cwd?: string } = {}\n\t): Promise<StreamedPHPResponse> {\n\t\tconst process = this[__private__dont__use].spawnProcess(\n\t\t\targv[0],\n\t\t\targv.slice(1),\n\t\t\t{\n\t\t\t\tenv: options.env,\n\t\t\t\tcwd: options.cwd ?? this.cwd(),\n\t\t\t}\n\t\t) as ChildProcess;\n\n\t\tconst stderrStream = await createInvertedReadableStream<Uint8Array>();\n\t\tprocess.on('error', (error) => {\n\t\t\tstderrStream.controller.error(error);\n\t\t});\n\t\tprocess.stderr.on('data', (data) => {\n\t\t\tstderrStream.controller.enqueue(data);\n\t\t});\n\n\t\tconst stdoutStream = await createInvertedReadableStream<Uint8Array>();\n\t\tprocess.stdout.on('data', (data) => {\n\t\t\tstdoutStream.controller.enqueue(data);\n\t\t});\n\n\t\tprocess.on('exit', () => {\n\t\t\t// Delay until next tick to ensure we don't close the streams before\n\t\t\t// emitting the error event on the stderrStream.\n\t\t\tsetTimeout(() => {\n\t\t\t\t/**\n\t\t\t\t * Ignore any close() errors, e.g. \"stream already closed\". We just\n\t\t\t\t * need to try to call close() and forget about this subprocess.\n\t\t\t\t */\n\t\t\t\ttry {\n\t\t\t\t\tstderrStream.controller.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tstdoutStream.controller.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t}, 0);\n\t\t});\n\n\t\treturn new StreamedPHPResponse(\n\t\t\t// Headers stream\n\t\t\tnew ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t}),\n\t\t\tstdoutStream.stream,\n\t\t\tstderrStream.stream,\n\t\t\t// Exit code\n\t\t\tnew Promise((resolve) => {\n\t\t\t\tprocess.on('exit', (code) => {\n\t\t\t\t\tresolve(code);\n\t\t\t\t});\n\t\t\t})\n\t\t);\n\t}\n\n\tsetSkipShebang(shouldSkip: boolean) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_skip_shebang',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[shouldSkip ? 1 : 0]\n\t\t);\n\t}\n\n\texit(code = 0) {\n\t\tthis.dispatchEvent({\n\t\t\ttype: 'runtime.beforeExit',\n\t\t});\n\t\ttry {\n\t\t\tthis[__private__dont__use]._exit(code);\n\t\t} catch {\n\t\t\t// ignore the exit error\n\t\t}\n\n\t\t// Clean up any initialized state\n\t\tthis.#phpWasmInitCalled = false;\n\n\t\t// Delete any links between this PHP instance and the runtime\n\t\tthis.#wasmErrorsTarget = null;\n\n\t\tif (this[__private__dont__use]) {\n\t\t\tdelete this[__private__dont__use]['onMessage'];\n\t\t\tdelete this[__private__dont__use];\n\t\t}\n\t}\n\n\t[Symbol.dispose]() {\n\t\tthis.exit(0);\n\t}\n}\n\nexport function normalizeHeaders(\n\theaders: PHPRequestHeaders\n): PHPRequestHeaders {\n\tconst normalized: PHPRequestHeaders = {};\n\tfor (const key in headers) {\n\t\tnormalized[key.toLowerCase()] = headers[key];\n\t}\n\treturn normalized;\n}\n\n/**\n * Copies the MEMFS directory structure from one FS in another FS.\n * Non-MEMFS nodes are ignored.\n */\nfunction copyMEMFSNodes(\n\tsource: Emscripten.FileSystemInstance,\n\ttarget: Emscripten.FileSystemInstance,\n\tpath: string\n) {\n\tif (\n\t\tgetNodeType(source, path) !== 'memfs' ||\n\t\t!['memfs', 'missing'].includes(getNodeType(target, path))\n\t) {\n\t\treturn;\n\t}\n\n\tconst oldNode = source.lookupPath(path);\n\tif (!source.isDir(oldNode.node.mode)) {\n\t\ttarget.writeFile(path, source.readFile(path));\n\t\treturn;\n\t}\n\n\ttarget.mkdirTree(path);\n\tconst filenames = source\n\t\t.readdir(path)\n\t\t.filter((name: string) => name !== '.' && name !== '..');\n\tfor (const filename of filenames) {\n\t\tcopyMEMFSNodes(source, target, joinPaths(path, filename));\n\t}\n}\n\n/**\n * Creates a readable stream with inverted control flow,\n * based on the specified underlying source.\n *\n * In this case, inverting control flow means exposing the controller\n * so the consumer can insert data into the stream.\n *\n * @param source - The underlying source to use.\n * @returns The resulting stream and its associated controller.\n */\nasync function createInvertedReadableStream<T = BufferSource>(\n\tsource: UnderlyingSource<T> = {}\n): Promise<{\n\tstream: ReadableStream<T>;\n\tcontroller: ReadableStreamDefaultController<T>;\n}> {\n\tlet controllerResolve: (\n\t\tcontroller: ReadableStreamDefaultController<T>\n\t) => void;\n\tconst controllerPromise = new Promise<ReadableStreamDefaultController<T>>(\n\t\t(resolve) => {\n\t\t\tcontrollerResolve = resolve;\n\t\t}\n\t);\n\n\tconst stream = new ReadableStream<T>({\n\t\t...source,\n\t\tstart(controller) {\n\t\t\t// Type assertion to handle the controller type mismatch\n\t\t\tcontrollerResolve(controller as ReadableStreamDefaultController<T>);\n\t\t\tif (source.start) {\n\t\t\t\treturn source.start(controller);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t});\n\n\tconst controller = await controllerPromise;\n\n\treturn {\n\t\tstream,\n\t\tcontroller,\n\t};\n}\n\nconst getNodeType = (fs: Emscripten.FileSystemInstance, path: string) => {\n\ttry {\n\t\tconst target = fs.lookupPath(path, { follow: true });\n\t\treturn 'contents' in target.node\n\t\t\t? 'memfs'\n\t\t\t: /**\n\t\t\t * Could be NODEFS, PROXYFS, etc.\n\t\t\t */\n\t\t\t 'not-memfs';\n\t} catch {\n\t\treturn 'missing';\n\t}\n};\n","import { PHP_INI_PATH } from './php';\nimport type { UniversalPHP } from './universal-php';\nimport { stringify, parse } from 'ini';\n\n/**\n * Reads the php.ini file and returns its entries.\n *\n * @param php The PHP instance.\n * @param entries Optional. If provided, only the specified entries will be returned.\n * @returns The php.ini entries.\n */\nexport async function getPhpIniEntries(php: UniversalPHP, entries?: string[]) {\n\tconst ini = parse(await php.readFileAsText(PHP_INI_PATH));\n\tif (entries === undefined) {\n\t\treturn ini;\n\t}\n\tconst result: Record<string, unknown> = {};\n\tfor (const key of entries) {\n\t\tresult[key] = ini[key];\n\t}\n\treturn result;\n}\n\n/**\n * Rewrites the php.ini file with the given entries.\n *\n * @param php The PHP instance.\n * @param entries The entries to write to the php.ini file.\n */\nexport async function setPhpIniEntries(\n\tphp: UniversalPHP,\n\tentries: Record<string, unknown>\n) {\n\tconst ini = parse(await php.readFileAsText(PHP_INI_PATH));\n\tfor (const [key, value] of Object.entries(entries)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tdelete ini[key];\n\t\t} else {\n\t\t\tini[key] = value;\n\t\t}\n\t}\n\tawait php.writeFile(PHP_INI_PATH, stringify(ini));\n}\n\n/**\n * Sets php.ini values to the given values, executes a callback,\n * and restores the original php.ini values. This is useful for\n * running code with temporary php.ini values, such as when\n * disabling network-related PHP functions just to run WordPress\n * installer.\n *\n * @example\n * ```ts\n *\tawait withPHPIniValues(\n *\t\tphp,\n *\t\t{\n *\t\t\tdisable_functions: 'fsockopen',\n *\t\t\tallow_url_fopen: '0',\n *\t\t},\n *\t\tasync () => await runWpInstallationWizard(php, {\n *\t\t\toptions: {},\n *\t\t})\n *\t);\n *\t```\n *\n * @param php The PHP instance.\n * @param phpIniValues The php.ini values to set.\n * @param callback The callback to execute.\n * @returns The result of the callback.\n */\nexport async function withPHPIniValues(\n\tphp: UniversalPHP,\n\tphpIniValues: Record<string, string>,\n\tcallback: () => Promise<any>\n) {\n\tconst iniBefore = await php.readFileAsText(PHP_INI_PATH);\n\ttry {\n\t\tawait setPhpIniEntries(php, phpIniValues);\n\t\treturn await callback();\n\t} finally {\n\t\tawait php.writeFile(PHP_INI_PATH, iniBefore);\n\t}\n}\n","import type { StreamedPHPResponse } from './php-response';\nimport { PHPResponse } from './php-response';\n\nexport async function printDebugDetails(\n\te: any,\n\tstreamedResponse?: StreamedPHPResponse\n) {\n\tif (streamedResponse) {\n\t\tprintResponseDebugDetails(\n\t\t\tawait PHPResponse.fromStreamedResponse(streamedResponse)\n\t\t);\n\t}\n\tawait prettyPrintFullStackTrace(e);\n}\n\n/**\n * Pretty prints the full stack trace of the error and all its causes.\n * Includes debug details for each error in the chain.\n * This is needed\n *\n * @param e\n */\nexport async function prettyPrintFullStackTrace(e: any) {\n\tlet current = e;\n\tlet isFirst = true;\n\twhile (current) {\n\t\tif (!isFirst) {\n\t\t\tprocess.stderr.write('\\nCaused by:\\n\\n');\n\t\t}\n\n\t\tprocess.stderr.write(current.originalErrorClassName ?? current.name);\n\t\tprocess.stderr.write(': ' + current.message + '\\n');\n\t\tprocess.stderr.write(\n\t\t\t(current.stack + '').split('\\n').slice(1).join('\\n')\n\t\t);\n\t\tprocess.stderr.write(`\\n`);\n\t\tif (current.response) {\n\t\t\tprintResponseDebugDetails(current.response);\n\t\t}\n\t\tif (current.phpLogs) {\n\t\t\tprocess.stderr.write(`\\n\\n==== PHP error log ====\\n\\n`);\n\t\t\tprocess.stderr.write(current.phpLogs);\n\t\t}\n\t\tcurrent = current.cause;\n\t\tisFirst = false;\n\t}\n\tprocess.stderr.write('\\n');\n}\n\nexport function printResponseDebugDetails(response: PHPResponse) {\n\t// Print a short summary of what we have:\n\tprocess.stderr.write(\n\t\t`\\n exitCode=${response.exitCode} httpStatusCode=${response.httpStatusCode} `\n\t);\n\tconst hasHeaders =\n\t\tresponse.headers && Object.keys(response.headers).length > 0;\n\tif (!hasHeaders) {\n\t\tprocess.stderr.write(`responseHeaders=(empty) `);\n\t}\n\tif (!response.text) {\n\t\tprocess.stderr.write(`stdout=(empty) `);\n\t}\n\tif (!response.errors) {\n\t\tprocess.stderr.write(`stderr=(empty) `);\n\t}\n\tprocess.stderr.write(`\\n`);\n\n\t// Print all the extended information in a separate section:\n\tif (hasHeaders) {\n\t\tprocess.stderr.write(\n\t\t\t`\\n==== PHP response headers ====\\n\\n${JSON.stringify(\n\t\t\t\tresponse.headers,\n\t\t\t\tnull,\n\t\t\t\t2\n\t\t\t)}\\n\\n`\n\t\t);\n\t}\n\n\tif (response.text) {\n\t\tprocess.stderr.write(`\\n==== PHP stdout ====\\n\\n`);\n\t\tprocess.stderr.write(response.text);\n\t}\n\n\tif (response.errors) {\n\t\tprocess.stderr.write(`\\n==== PHP stderr ====\\n\\n`);\n\t\tprocess.stderr.write(response.errors);\n\t}\n\tprocess.stderr.write(`\\n`);\n}\n","import { logger } from '@php-wasm/logger';\nimport type { CookieStore } from './php-request-handler';\n/**\n * @public\n */\nexport class HttpCookieStore implements CookieStore {\n\tcookies: Record<string, string> = {};\n\n\trememberCookiesFromResponseHeaders(headers: Record<string, string[]>) {\n\t\tif (!headers?.['set-cookie']) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const setCookie of headers['set-cookie']) {\n\t\t\ttry {\n\t\t\t\tif (!setCookie.includes('=')) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst equalsIndex = setCookie.indexOf('=');\n\t\t\t\tconst name = setCookie.substring(0, equalsIndex);\n\t\t\t\tconst value = setCookie\n\t\t\t\t\t.substring(equalsIndex + 1)\n\t\t\t\t\t.split(';')[0];\n\t\t\t\tthis.cookies[name] = value;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tgetCookieRequestHeader() {\n\t\tconst cookiesArray: string[] = [];\n\t\tfor (const name in this.cookies) {\n\t\t\tcookiesArray.push(`${name}=${this.cookies[name]}`);\n\t\t}\n\t\treturn cookiesArray.join('; ');\n\t}\n}\n","import type { UniversalPHP } from './universal-php';\n\n/**\n * Reads a file from PHP filesystem using a stream.\n */\nexport function streamReadFileFromPHP(php: UniversalPHP, path: string) {\n\treturn new ReadableStream({\n\t\tasync pull(controller) {\n\t\t\tconst buffer = await php.readFileAsBuffer(path);\n\t\t\tcontroller.enqueue(buffer);\n\t\t\tcontroller.close();\n\t\t},\n\t});\n}\n","import { joinPaths, normalizePath } from '@php-wasm/util';\nimport { StreamedFile } from '@php-wasm/stream-compression';\nimport type { UniversalPHP } from './universal-php';\nimport { streamReadFileFromPHP } from './stream-read-file-from-php';\n\nexport type IteratePhpFilesOptions = {\n\t/**\n\t * Should yield paths relative to the root directory?\n\t * If false, all paths will be absolute.\n\t */\n\trelativePaths?: boolean;\n\n\t/**\n\t * A prefix to add to all paths.\n\t * Only used if `relativePaths` is true.\n\t */\n\tpathPrefix?: string;\n\n\t/**\n\t * A list of paths to exclude from the results.\n\t */\n\texceptPaths?: string[];\n};\n\n/**\n * Iterates over all files in a php directory and its subdirectories.\n *\n * @param php - The PHP instance.\n * @param root - The root directory to start iterating from.\n * @param options - Optional configuration.\n * @returns All files found in the tree.\n */\nexport async function* iteratePhpFiles(\n\tphp: UniversalPHP,\n\troot: string,\n\t{\n\t\trelativePaths = true,\n\t\tpathPrefix,\n\t\texceptPaths = [],\n\t}: IteratePhpFilesOptions = {}\n): AsyncGenerator<File> {\n\troot = normalizePath(root);\n\tconst stack: string[] = [root];\n\twhile (stack.length) {\n\t\tconst currentParent = stack.pop();\n\t\tif (!currentParent) {\n\t\t\treturn;\n\t\t}\n\t\tconst files = await php.listFiles(currentParent);\n\t\tfor (const file of files) {\n\t\t\tconst absPath = `${currentParent}/${file}`;\n\t\t\tif (exceptPaths.includes(absPath.substring(root.length + 1))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst isDir = await php.isDir(absPath);\n\t\t\tif (isDir) {\n\t\t\t\tstack.push(absPath);\n\t\t\t} else {\n\t\t\t\tyield new StreamedFile(\n\t\t\t\t\tstreamReadFileFromPHP(php, absPath),\n\t\t\t\t\trelativePaths\n\t\t\t\t\t\t? joinPaths(\n\t\t\t\t\t\t\t\tpathPrefix || '',\n\t\t\t\t\t\t\t\tabsPath.substring(root.length + 1)\n\t\t\t\t\t\t )\n\t\t\t\t\t\t: absPath\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { dirname, joinPaths } from '@php-wasm/util';\nimport type { UniversalPHP } from './universal-php';\n\n/**\n * Writes streamed files to PHP filesystem.\n */\nexport function writeFilesStreamToPhp(php: UniversalPHP, root: string) {\n\treturn new WritableStream({\n\t\tasync write(file: File) {\n\t\t\tconst filePath = joinPaths(root, file.name);\n\t\t\tif (file.type === 'directory') {\n\t\t\t\tawait php.mkdir(filePath);\n\t\t\t} else {\n\t\t\t\tawait php.mkdir(dirname(filePath));\n\t\t\t\tawait php.writeFile(\n\t\t\t\t\tfilePath,\n\t\t\t\t\tnew Uint8Array(await file.arrayBuffer())\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t});\n}\n","import { AcquireTimeoutError, Semaphore } from '@php-wasm/util';\nimport type { PHP } from './php';\n\nexport type PHPFactoryOptions = {\n\tisPrimary: boolean;\n};\n\nexport type PHPFactory = (options: PHPFactoryOptions) => Promise<PHP>;\n\nexport interface ProcessManagerOptions {\n\t/**\n\t * The maximum number of PHP instances that can exist at\n\t * the same time.\n\t */\n\tmaxPhpInstances?: number;\n\t/**\n\t * The number of milliseconds to wait for a PHP instance when\n\t * we have reached the maximum number of PHP instances and\n\t * cannot spawn a new one. If the timeout is reached, we assume\n\t * all the PHP instances are deadlocked and a throw MaxPhpInstancesError.\n\t *\n\t * Default: 5000\n\t */\n\ttimeout?: number;\n\t/**\n\t * The primary PHP instance that's never killed. This instance\n\t * contains the reference filesystem used by all other PHP instances.\n\t */\n\tprimaryPhp?: PHP;\n\t/**\n\t * A factory function used for spawning new PHP instances.\n\t */\n\tphpFactory?: PHPFactory;\n}\n\nexport interface SpawnedPHP {\n\tphp: PHP;\n\treap: () => void;\n}\n\nexport class MaxPhpInstancesError extends Error {\n\tconstructor(limit: number) {\n\t\tsuper(\n\t\t\t`Requested more concurrent PHP instances than the limit (${limit}).`\n\t\t);\n\t\tthis.name = this.constructor.name;\n\t}\n}\n\n/**\n * A PHP Process manager.\n *\n * Maintains:\n * * A single \"primary\" PHP instance that's never killed – it contains the\n * reference filesystem used by all other PHP instances.\n * * A pool of disposable PHP instances that are spawned to handle a single\n * request and reaped immediately after.\n *\n * When a new request comes in, PHPProcessManager yields the idle instance to\n * handle it, and immediately starts initializing a new idle instance. In other\n * words, for n concurrent requests, there are at most n+1 PHP instances\n * running at the same time.\n *\n * A slight nuance is that the first idle instance is not initialized until the\n * first concurrent request comes in. This is because many use-cases won't\n * involve parallel requests and, for those, we can avoid eagerly spinning up a\n * second PHP instance.\n *\n * This strategy is inspired by Cowboy, an Erlang HTTP server. Handling a\n * single extra request can happen immediately, while handling multiple extra\n * requests requires extra time to spin up a few PHP instances. This is a more\n * resource-friendly tradeoff than keeping 5 idle instances at all times.\n */\nexport class PHPProcessManager implements AsyncDisposable {\n\tprivate primaryPhp?: PHP;\n\tprivate primaryPhpPromise?: Promise<SpawnedPHP>;\n\tprivate primaryIdle = true;\n\tprivate nextInstance: Promise<SpawnedPHP> | null = null;\n\t/**\n\t * All spawned PHP instances, including the primary PHP instance.\n\t * Used for bookkeeping and reaping all instances on dispose.\n\t */\n\tprivate allInstances: Promise<SpawnedPHP>[] = [];\n\tprivate phpFactory?: PHPFactory;\n\tprivate maxPhpInstances: number;\n\tprivate semaphore: Semaphore;\n\n\tconstructor(options?: ProcessManagerOptions) {\n\t\tthis.maxPhpInstances = options?.maxPhpInstances ?? 5;\n\t\tthis.phpFactory = options?.phpFactory;\n\t\tthis.primaryPhp = options?.primaryPhp;\n\t\tthis.semaphore = new Semaphore({\n\t\t\tconcurrency: this.maxPhpInstances,\n\t\t\t/**\n\t\t\t * Wait up to 5 seconds for resources to become available\n\t\t\t * before assuming that all the PHP instances are deadlocked.\n\t\t\t */\n\t\t\ttimeout: options?.timeout || 5000,\n\t\t});\n\t}\n\n\t/**\n\t * Get the primary PHP instance.\n\t *\n\t * If the primary PHP instance is not set, it will be spawned\n\t * using the provided phpFactory.\n\t *\n\t * @throws {Error} when called twice before the first call is resolved.\n\t */\n\tasync getPrimaryPhp() {\n\t\tif (!this.phpFactory && !this.primaryPhp) {\n\t\t\tthrow new Error(\n\t\t\t\t'phpFactory or primaryPhp must be set before calling getPrimaryPhp().'\n\t\t\t);\n\t\t} else if (!this.primaryPhp) {\n\t\t\tif (!this.primaryPhpPromise) {\n\t\t\t\tthis.primaryPhpPromise = this.spawn({ isPrimary: true });\n\t\t\t}\n\t\t\tthis.primaryPhp = (await this.primaryPhpPromise).php;\n\t\t\tthis.primaryPhpPromise = undefined;\n\t\t}\n\t\treturn this.primaryPhp!;\n\t}\n\n\t/**\n\t * Get a PHP instance.\n\t *\n\t * It could be either the primary PHP instance, an idle disposable PHP\n\t * instance, or a newly spawned PHP instance – depending on the resource\n\t * availability.\n\t *\n\t * @param considerPrimary - Whether to consider the primary PHP instance.\n\t * It matters because PHP.cli() sets the SAPI to CLI and\n\t * kills the entire process after it finishes running,\n\t * making the primary PHP instance non-reusable for\n\t * subsequent .run() calls. This is fine for one-off\n\t * child PHP instances, but not for the primary PHP\n\t * that's meant to continue working for the entire duration\n\t * of the ProcessManager lifetime. Therefore, we don't\n\t * consider the primary PHP instance by default unless\n\t * the caller explicitly requests it.\n\t *\n\t * @throws {MaxPhpInstancesError} when the maximum number of PHP instances is reached\n\t * and the waiting timeout is exceeded.\n\t */\n\tasync acquirePHPInstance({\n\t\tconsiderPrimary = false,\n\t}: {\n\t\tconsiderPrimary?: boolean;\n\t} = {}): Promise<SpawnedPHP> {\n\t\t/**\n\t\t * First and foremost, make sure we have the primary PHP instance in place.\n\t\t * We may not actually acquire it. We just need it to exist.\n\t\t *\n\t\t * @TODO: Re-evaluate why we need it to exist. Should spawn() be just more\n\t\t * lenient with its \"another primary instance already started spawning\"\n\t\t * check?\n\t\t */\n\t\tif (!this.primaryPhp) {\n\t\t\tawait this.getPrimaryPhp();\n\t\t}\n\n\t\tif (this.primaryIdle && considerPrimary) {\n\t\t\tthis.primaryIdle = false;\n\t\t\treturn {\n\t\t\t\tphp: await this.getPrimaryPhp(),\n\t\t\t\treap: () => {\n\t\t\t\t\tthis.primaryIdle = true;\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t/**\n\t\t * nextInstance is null:\n\t\t *\n\t\t * * Before the first concurrent getInstance() call\n\t\t * * When the last getInstance() call did not have enough\n\t\t * budget left to optimistically start spawning the next\n\t\t * instance.\n\t\t */\n\t\tconst spawnedPhp =\n\t\t\tthis.nextInstance || this.spawn({ isPrimary: false });\n\n\t\t/**\n\t\t * Start spawning the next instance if there's still room. We can't\n\t\t * just always spawn the next instance because spawn() can fail\n\t\t * asynchronously and then we'll get an unhandled promise rejection.\n\t\t */\n\t\tif (this.semaphore.remaining > 0) {\n\t\t\tthis.nextInstance = this.spawn({ isPrimary: false });\n\t\t} else {\n\t\t\tthis.nextInstance = null;\n\t\t}\n\t\treturn await spawnedPhp;\n\t}\n\n\t/**\n\t * Initiated spawning of a new PHP instance.\n\t * This function is synchronous on purpose – it needs to synchronously\n\t * add the spawn promise to the allInstances array without waiting\n\t * for PHP to spawn.\n\t */\n\tprivate spawn(factoryArgs: PHPFactoryOptions): Promise<SpawnedPHP> {\n\t\tif (factoryArgs.isPrimary && this.allInstances.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t'Requested spawning a primary PHP instance when another primary instance already started spawning.'\n\t\t\t);\n\t\t}\n\t\tconst spawned = this.doSpawn(factoryArgs);\n\t\tthis.allInstances.push(spawned);\n\t\tconst pop = () => {\n\t\t\tthis.allInstances = this.allInstances.filter(\n\t\t\t\t(instance) => instance !== spawned\n\t\t\t);\n\t\t};\n\t\treturn spawned\n\t\t\t.catch((rejection) => {\n\t\t\t\tpop();\n\t\t\t\tthrow rejection;\n\t\t\t})\n\t\t\t.then((result) => ({\n\t\t\t\t...result,\n\t\t\t\treap: () => {\n\t\t\t\t\tpop();\n\t\t\t\t\tresult.reap();\n\t\t\t\t},\n\t\t\t}));\n\t}\n\n\t/**\n\t * Actually acquires the lock and spawns a new PHP instance.\n\t */\n\tprivate async doSpawn(factoryArgs: PHPFactoryOptions): Promise<SpawnedPHP> {\n\t\tlet release: () => void;\n\t\ttry {\n\t\t\trelease = await this.semaphore.acquire();\n\t\t} catch (error) {\n\t\t\tif (error instanceof AcquireTimeoutError) {\n\t\t\t\tthrow new MaxPhpInstancesError(this.maxPhpInstances);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\ttry {\n\t\t\tconst php = await this.phpFactory!(factoryArgs);\n\t\t\treturn {\n\t\t\t\tphp,\n\t\t\t\treap() {\n\t\t\t\t\tphp.exit();\n\t\t\t\t\trelease();\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (e) {\n\t\t\trelease();\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync [Symbol.asyncDispose]() {\n\t\tif (this.primaryPhp) {\n\t\t\tthis.primaryPhp.exit();\n\t\t}\n\t\tawait Promise.all(\n\t\t\tthis.allInstances.map((instance) =>\n\t\t\t\tinstance.then(({ reap }) => reap())\n\t\t\t)\n\t\t);\n\t}\n}\n","export const SupportedPHPVersions = [\n\t'8.4',\n\t'8.3',\n\t'8.2',\n\t'8.1',\n\t'8.0',\n\t'7.4',\n\t'7.3',\n\t'7.2',\n] as const;\nexport const LatestSupportedPHPVersion = SupportedPHPVersions[0];\nexport const SupportedPHPVersionsList = SupportedPHPVersions as any as string[];\nexport type SupportedPHPVersion = (typeof SupportedPHPVersions)[number];\n","/**\n * The default base used to convert a path into the URL object.\n */\nexport const DEFAULT_BASE_URL = 'http://example.com';\n\n/**\n * Returns a string representing the path, query, and\n * fragment of the given URL.\n *\n * @example\n * ```js\n * const url = new URL('http://example.com/foo/bar?baz=qux#quux');\n * toRelativeUrl(url); // '/foo/bar?baz=qux#quux'\n * ```\n *\n * @param url The URL.\n * @returns The path, query, and fragment.\n */\nexport function toRelativeUrl(url: URL): string {\n\t/**\n\t * The origin of an about:blank URL is a string \"null\". The URL is not\n\t * relative, but there's also nothing we can do to make it \"more relative\"\n\t * so let's just bale out and return the URL as is.\n\t *\n\t * @see https://html.spec.whatwg.org/multipage/browsers.html#concept-origin (Opaque origins)\n\t */\n\tif (url.origin === 'null') {\n\t\treturn url.toString();\n\t}\n\treturn url.toString().substring(url.origin.length);\n}\n\n/**\n * Removes the given prefix from the given path.\n *\n * @example\n * ```js\n * removePathPrefix('/foo/bar', '/foo'); // '/bar'\n * removePathPrefix('/bar', '/foo'); // '/bar'\n * ```\n *\n * @param path The path to remove the prefix from.\n * @param prefix The prefix to remove.\n * @returns Path with the prefix removed.\n */\nexport function removePathPrefix(path: string, prefix: string): string {\n\tif (!prefix || !path.startsWith(prefix)) {\n\t\treturn path;\n\t}\n\treturn path.substring(prefix.length);\n}\n\n/**\n * Ensures the given path has the given prefix.\n *\n * @example\n * ```js\n * ensurePathPrefix('/bar', '/foo'); // '/foo/bar'\n * ensurePathPrefix('/foo/bar', '/foo'); // '/foo/bar'\n * ```\n *\n * @param path\n * @param prefix\n * @returns Path with the prefix added.\n */\nexport function ensurePathPrefix(path: string, prefix: string): string {\n\tif (!prefix || path.startsWith(prefix)) {\n\t\treturn path;\n\t}\n\treturn prefix + path;\n}\n","/**\n * Encodes a multipart/form-data request body.\n *\n * @param data - The form data to encode.\n * @returns The encoded body and a correctly formatted content type header.\n */\nexport async function encodeAsMultipart(\n\tdata: Record<string, string | Uint8Array | File>\n) {\n\tconst boundary = `----${Math.random().toString(36).slice(2)}`;\n\tconst contentType = `multipart/form-data; boundary=${boundary}`;\n\n\tconst textEncoder = new TextEncoder();\n\tconst parts: (string | Uint8Array)[] = [];\n\tfor (const [name, value] of Object.entries(data)) {\n\t\tparts.push(`--${boundary}\\r\\n`);\n\t\tparts.push(`Content-Disposition: form-data; name=\"${name}\"`);\n\t\tif (value instanceof File) {\n\t\t\tparts.push(`; filename=\"${value.name}\"`);\n\t\t}\n\t\tparts.push(`\\r\\n`);\n\t\tif (value instanceof File) {\n\t\t\tparts.push(`Content-Type: application/octet-stream`);\n\t\t\tparts.push(`\\r\\n`);\n\t\t}\n\t\tparts.push(`\\r\\n`);\n\t\tif (value instanceof File) {\n\t\t\tparts.push(await fileToUint8Array(value));\n\t\t} else {\n\t\t\tparts.push(value);\n\t\t}\n\t\tparts.push(`\\r\\n`);\n\t}\n\tparts.push(`--${boundary}--\\r\\n`);\n\n\tconst length = parts.reduce((acc, part) => acc + part.length, 0);\n\tconst bytes = new Uint8Array(length);\n\tlet offset = 0;\n\tfor (const part of parts) {\n\t\tbytes.set(\n\t\t\ttypeof part === 'string' ? textEncoder.encode(part) : part,\n\t\t\toffset\n\t\t);\n\t\toffset += part.length;\n\t}\n\treturn { bytes, contentType };\n}\n\nfunction fileToUint8Array(file: File): Promise<Uint8Array> {\n\t/**\n\t * @mbuella: Use File.arrayBuffer() to get a Uint8Array from a file, avoiding FileReader\n\t * which is browser-specific. This method is supported in major browsers and NodeJS/Deno runtimes.\n\t */\n\treturn file.arrayBuffer().then((fileBuffer) => new Uint8Array(fileBuffer));\n}\n","import { dirname, joinPaths } from '@php-wasm/util';\nimport {\n\tensurePathPrefix,\n\ttoRelativeUrl,\n\tremovePathPrefix,\n\tDEFAULT_BASE_URL,\n} from './urls';\nimport type { PHP, PHPExecutionFailureError } from './php';\nimport { normalizeHeaders } from './php';\nimport { PHPResponse } from './php-response';\nimport type { PHPRequest, PHPRunOptions } from './universal-php';\nimport { encodeAsMultipart } from './encode-as-multipart';\nimport type { PHPFactoryOptions, SpawnedPHP } from './php-process-manager';\nimport { MaxPhpInstancesError, PHPProcessManager } from './php-process-manager';\nimport { HttpCookieStore } from './http-cookie-store';\nimport mimeTypes from './mime-types.json';\n\nexport type RewriteRule = {\n\tmatch: RegExp;\n\treplacement: string;\n};\n\nexport type FileNotFoundToResponse = {\n\ttype: 'response';\n\tresponse: PHPResponse;\n};\nexport type FileNotFoundToInternalRedirect = {\n\ttype: 'internal-redirect';\n\turi: string;\n};\nexport type FileNotFoundTo404 = { type: '404' };\n\nexport type FileNotFoundAction =\n\t| FileNotFoundToResponse\n\t| FileNotFoundToInternalRedirect\n\t| FileNotFoundTo404;\n\nexport type FileNotFoundGetActionCallback = (\n\trelativePath: string\n) => FileNotFoundAction;\n\n/**\n * Interface for cookie storage implementations.\n * This allows different cookie handling strategies to be used with the PHP request handler.\n */\nexport interface CookieStore {\n\t/**\n\t * Processes and stores cookies from response headers\n\t * @param headers Response headers containing Set-Cookie directives\n\t */\n\trememberCookiesFromResponseHeaders(headers: Record<string, string[]>): void;\n\n\t/**\n\t * Gets the cookie header string for the next request\n\t * @returns Formatted cookie header string\n\t */\n\tgetCookieRequestHeader(): string;\n}\n\ninterface BaseConfiguration {\n\t/**\n\t * The directory in the PHP filesystem where the server will look\n\t * for the files to serve. Default: `/var/www`.\n\t */\n\tdocumentRoot?: string;\n\t/**\n\t * Request Handler URL. Used to populate $_SERVER details like HTTP_HOST.\n\t */\n\tabsoluteUrl?: string;\n\n\t/**\n\t * Rewrite rules\n\t */\n\trewriteRules?: RewriteRule[];\n\n\t/**\n\t * A callback that decides how to handle a file-not-found condition for a\n\t * given request URI.\n\t */\n\tgetFileNotFoundAction?: FileNotFoundGetActionCallback;\n}\n\nexport type PHPRequestHandlerFactoryArgs = PHPFactoryOptions & {\n\trequestHandler: PHPRequestHandler;\n};\n\nexport type PHPRequestHandlerConfiguration = BaseConfiguration &\n\t(\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * PHPProcessManager is required because the request handler needs\n\t\t\t\t * to make a decision for each request.\n\t\t\t\t *\n\t\t\t\t * Static assets are served using the primary PHP's filesystem, even\n\t\t\t\t * when serving 100 static files concurrently. No new PHP interpreter\n\t\t\t\t * is ever created as there's no need for it.\n\t\t\t\t *\n\t\t\t\t * Dynamic PHP requests, however, require grabbing an available PHP\n\t\t\t\t * interpreter, and that's where the PHPProcessManager comes in.\n\t\t\t\t */\n\t\t\t\tprocessManager: PHPProcessManager;\n\t\t }\n\t\t| {\n\t\t\t\tphpFactory: (\n\t\t\t\t\trequestHandler: PHPRequestHandlerFactoryArgs\n\t\t\t\t) => Promise<PHP>;\n\t\t\t\t/**\n\t\t\t\t * The maximum number of PHP instances that can exist at\n\t\t\t\t * the same time.\n\t\t\t\t */\n\t\t\t\tmaxPhpInstances?: number;\n\t\t }\n\t) & {\n\t\tcookieStore?: CookieStore | false;\n\t};\n\n/**\n * Handles HTTP requests using PHP runtime as a backend.\n *\n * @public\n * @example Use PHPRequestHandler implicitly with a new PHP instance:\n * ```js\n * import { PHP } from '@php-wasm/web';\n *\n * const php = await PHP.load( '7.4', {\n * requestHandler: {\n * // PHP FS path to serve the files from:\n * documentRoot: '/www',\n *\n * // Used to populate $_SERVER['SERVER_NAME'] etc.:\n * absoluteUrl: 'http://127.0.0.1'\n * }\n * } );\n *\n * php.mkdirTree('/www');\n * php.writeFile('/www/index.php', '<?php echo \"Hi from PHP!\"; ');\n *\n * const response = await php.request({ path: '/index.php' });\n * console.log(response.text);\n * // \"Hi from PHP!\"\n * ```\n *\n * @example Explicitly create a PHPRequestHandler instance and run a PHP script:\n * ```js\n * import {\n * loadPHPRuntime,\n * PHP,\n * PHPRequestHandler,\n * getPHPLoaderModule,\n * } from '@php-wasm/web';\n *\n * const runtime = await loadPHPRuntime( await getPHPLoaderModule('7.4') );\n * const php = new PHP( runtime );\n *\n * php.mkdirTree('/www');\n * php.writeFile('/www/index.php', '<?php echo \"Hi from PHP!\"; ');\n *\n * const server = new PHPRequestHandler(php, {\n * // PHP FS path to serve the files from:\n * documentRoot: '/www',\n *\n * // Used to populate $_SERVER['SERVER_NAME'] etc.:\n * absoluteUrl: 'http://127.0.0.1'\n * });\n *\n * const response = server.request({ path: '/index.php' });\n * console.log(response.text);\n * // \"Hi from PHP!\"\n * ```\n */\nexport class PHPRequestHandler implements AsyncDisposable {\n\t#DOCROOT: string;\n\t#PROTOCOL: string;\n\t#HOSTNAME: string;\n\t#PORT: number;\n\t#HOST: string;\n\t#PATHNAME: string;\n\t#ABSOLUTE_URL: string;\n\t#cookieStore: CookieStore | false;\n\trewriteRules: RewriteRule[];\n\tprocessManager: PHPProcessManager;\n\tgetFileNotFoundAction: FileNotFoundGetActionCallback;\n\n\t/**\n\t * The request handler needs to decide whether to serve a static asset or\n\t * run the PHP interpreter. For static assets it should just reuse the primary\n\t * PHP even if there's 50 concurrent requests to serve. However, for\n\t * dynamic PHP requests, it needs to grab an available interpreter.\n\t * Therefore, it cannot just accept PHP as an argument as serving requests\n\t * requires access to ProcessManager.\n\t *\n\t * @param php - The PHP instance.\n\t * @param config - Request Handler configuration.\n\t */\n\tconstructor(config: PHPRequestHandlerConfiguration) {\n\t\tconst {\n\t\t\tdocumentRoot = '/www/',\n\t\t\tabsoluteUrl = typeof location === 'object'\n\t\t\t\t? location.href\n\t\t\t\t: DEFAULT_BASE_URL,\n\t\t\trewriteRules = [],\n\t\t\tgetFileNotFoundAction = () => ({ type: '404' }),\n\t\t} = config;\n\n\t\tif ('processManager' in config) {\n\t\t\tthis.processManager = config.processManager;\n\t\t} else {\n\t\t\tthis.processManager = new PHPProcessManager({\n\t\t\t\tphpFactory: async (info) => {\n\t\t\t\t\tconst php = await config.phpFactory!({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\trequestHandler: this,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Always set managed PHP's cwd to the document root.\n\t\t\t\t\tif (!php.isDir(documentRoot)) {\n\t\t\t\t\t\tphp.mkdir(documentRoot);\n\t\t\t\t\t}\n\t\t\t\t\tphp.chdir(documentRoot);\n\n\t\t\t\t\t// @TODO: Decouple PHP and request handler\n\t\t\t\t\t(php as any).requestHandler = this;\n\t\t\t\t\treturn php;\n\t\t\t\t},\n\t\t\t\tmaxPhpInstances: config.maxPhpInstances,\n\t\t\t});\n\t\t}\n\n\t\t/**\n\t\t * By default, config.cookieStore is undefined, so we use the\n\t\t * HttpCookieStore implementation, otherwise we use the one\n\t\t * provided in the config.\n\t\t *\n\t\t * By explicitly checking for `undefined` we allow the user to pass\n\t\t * `null` as config.cookieStore and disable the cookie store.\n\t\t */\n\t\tthis.#cookieStore =\n\t\t\tconfig.cookieStore === undefined\n\t\t\t\t? new HttpCookieStore()\n\t\t\t\t: config.cookieStore;\n\t\tthis.#DOCROOT = documentRoot;\n\n\t\tconst url = new URL(absoluteUrl);\n\t\tthis.#HOSTNAME = url.hostname;\n\t\tthis.#PORT = url.port\n\t\t\t? Number(url.port)\n\t\t\t: url.protocol === 'https:'\n\t\t\t? 443\n\t\t\t: 80;\n\t\tthis.#PROTOCOL = (url.protocol || '').replace(':', '');\n\t\tconst isNonStandardPort = this.#PORT !== 443 && this.#PORT !== 80;\n\t\tthis.#HOST = [\n\t\t\tthis.#HOSTNAME,\n\t\t\tisNonStandardPort ? `:${this.#PORT}` : '',\n\t\t].join('');\n\t\tthis.#PATHNAME = url.pathname.replace(/\\/+$/, '');\n\t\tthis.#ABSOLUTE_URL = [\n\t\t\t`${this.#PROTOCOL}://`,\n\t\t\tthis.#HOST,\n\t\t\tthis.#PATHNAME,\n\t\t].join('');\n\t\tthis.rewriteRules = rewriteRules;\n\t\tthis.getFileNotFoundAction = getFileNotFoundAction;\n\t}\n\n\tasync getPrimaryPhp() {\n\t\treturn await this.processManager.getPrimaryPhp();\n\t}\n\n\t/**\n\t * Converts a path to an absolute URL based at the PHPRequestHandler\n\t * root.\n\t *\n\t * @param path The server path to convert to an absolute URL.\n\t * @returns The absolute URL.\n\t */\n\tpathToInternalUrl(path: string): string {\n\t\tif (!path.startsWith('/')) {\n\t\t\tpath = `/${path}`;\n\t\t}\n\t\treturn `${this.absoluteUrl}${path}`;\n\t}\n\n\t/**\n\t * Converts an absolute URL based at the PHPRequestHandler to a relative path\n\t * without the server pathname and scope.\n\t *\n\t * @param internalUrl An absolute URL based at the PHPRequestHandler root.\n\t * @returns The relative path.\n\t */\n\tinternalUrlToPath(internalUrl: string): string {\n\t\tconst url = new URL(internalUrl, 'https://playground.internal');\n\t\tif (url.pathname.startsWith(this.#PATHNAME)) {\n\t\t\turl.pathname = url.pathname.slice(this.#PATHNAME.length);\n\t\t}\n\t\treturn toRelativeUrl(url);\n\t}\n\n\t/**\n\t * The absolute URL of this PHPRequestHandler instance.\n\t */\n\tget absoluteUrl() {\n\t\treturn this.#ABSOLUTE_URL;\n\t}\n\n\t/**\n\t * The directory in the PHP filesystem where the server will look\n\t * for the files to serve. Default: `/var/www`.\n\t */\n\tget documentRoot() {\n\t\treturn this.#DOCROOT;\n\t}\n\n\t/**\n\t * Serves the request – either by serving a static file, or by\n\t * dispatching it to the PHP runtime.\n\t *\n\t * The request() method mode behaves like a web server and only works if\n\t * the PHP was initialized with a `requestHandler` option (which the online\n\t * version of WordPress Playground does by default).\n\t *\n\t * In the request mode, you pass an object containing the request information\n\t * (method, headers, body, etc.) and the path to the PHP file to run:\n\t *\n\t * ```ts\n\t * const php = PHP.load('7.4', {\n\t * \trequestHandler: {\n\t * \t\tdocumentRoot: \"/www\"\n\t * \t}\n\t * })\n\t * php.writeFile(\"/www/index.php\", `<?php echo file_get_contents(\"php://input\");`);\n\t * const result = await php.request({\n\t * \tmethod: \"GET\",\n\t * \theaders: {\n\t * \t\t\"Content-Type\": \"text/plain\"\n\t * \t},\n\t * \tbody: \"Hello world!\",\n\t * \tpath: \"/www/index.php\"\n\t * });\n\t * // result.text === \"Hello world!\"\n\t * ```\n\t *\n\t * The `request()` method cannot be used in conjunction with `cli()`.\n\t *\n\t * @example\n\t * ```js\n\t * const output = await php.request({\n\t * \tmethod: 'GET',\n\t * \turl: '/index.php',\n\t * \theaders: {\n\t * \t\t'X-foo': 'bar',\n\t * \t},\n\t * \tbody: {\n\t * \t\tfoo: 'bar',\n\t * \t},\n\t * });\n\t * console.log(output.stdout); // \"Hello world!\"\n\t * ```\n\t *\n\t * @param request - PHP Request data.\n\t */\n\tasync request(request: PHPRequest): Promise<PHPResponse> {\n\t\tconst isAbsolute = URL.canParse(request.url);\n\t\tconst originalRequestUrl = new URL(\n\t\t\t// Remove the hash part of the URL as it's not meant for the server.\n\t\t\trequest.url.split('#')[0],\n\t\t\tisAbsolute ? undefined : DEFAULT_BASE_URL\n\t\t);\n\n\t\tconst rewrittenRequestUrl = this.#applyRewriteRules(originalRequestUrl);\n\t\tconst primaryPhp = await this.getPrimaryPhp();\n\t\tlet fsPath = joinPaths(\n\t\t\tthis.#DOCROOT,\n\t\t\t/**\n\t\t\t * Turn a URL such as `https://playground/scope:my-site/wp-admin/index.php`\n\t\t\t * into a site-relative path, such as `/wp-admin/index.php`.\n\t\t\t */\n\t\t\tremovePathPrefix(\n\t\t\t\t/**\n\t\t\t\t * URL.pathname returns a URL-encoded path. We need to decode it\n\t\t\t\t * before using it as a filesystem path.\n\t\t\t\t */\n\t\t\t\tdecodeURIComponent(rewrittenRequestUrl.pathname),\n\t\t\t\tthis.#PATHNAME\n\t\t\t)\n\t\t);\n\t\tif (primaryPhp.isDir(fsPath)) {\n\t\t\t// Ensure directory URIs have a trailing slash. Otherwise,\n\t\t\t// relative URIs in index.php or index.html files are relative\n\t\t\t// to the next directory up.\n\t\t\t//\n\t\t\t// Example:\n\t\t\t// For an index page served for URI \"/settings\", we naturally expect\n\t\t\t// links to be relative to \"/settings\", but without the trailing\n\t\t\t// slash, a relative link \"edit.php\" resolves to \"/edit.php\"\n\t\t\t// rather than \"/settings/edit.php\".\n\t\t\t//\n\t\t\t// This treatment of relative links is correct behavior for the browser:\n\t\t\t// https://www.rfc-editor.org/rfc/rfc3986#section-5.2.3\n\t\t\t//\n\t\t\t// But user intent for `/settings/index.php` is that its relative\n\t\t\t// URIs are relative to `/settings/`. So we redirect to add a\n\t\t\t// trailing slash to directory URIs to meet this expecatation.\n\t\t\t//\n\t\t\t// This behavior is also necessary for WordPress to function properly.\n\t\t\t// Otherwise, when viewing the WP admin dashboard at `/wp-admin`,\n\t\t\t// links to other admin pages like `edit.php` will incorrectly\n\t\t\t// resolve to `/edit.php` rather than `/wp-admin/edit.php`.\n\t\t\tif (!fsPath.endsWith('/')) {\n\t\t\t\treturn new PHPResponse(\n\t\t\t\t\t301,\n\t\t\t\t\t{ Location: [`${rewrittenRequestUrl.pathname}/`] },\n\t\t\t\t\tnew Uint8Array(0)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// We can only satisfy requests for directories with a default file\n\t\t\t// so let's first resolve to a default path when available.\n\t\t\tfor (const possibleIndexFile of ['index.php', 'index.html']) {\n\t\t\t\tconst possibleIndexPath = joinPaths(fsPath, possibleIndexFile);\n\t\t\t\tif (primaryPhp.isFile(possibleIndexPath)) {\n\t\t\t\t\tfsPath = possibleIndexPath;\n\n\t\t\t\t\t// Include the resolved index file in the final rewritten request URL.\n\t\t\t\t\trewrittenRequestUrl.pathname = joinPaths(\n\t\t\t\t\t\trewrittenRequestUrl.pathname,\n\t\t\t\t\t\tpossibleIndexFile\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!primaryPhp.isFile(fsPath)) {\n\t\t\t/**\n\t\t\t * Try resolving a partial path.\n\t\t\t *\n\t\t\t * Example:\n\t\t\t *\n\t\t\t * – Request URL: /file.php/index.php\n\t\t\t * – Document Root: /var/www\n\t\t\t *\n\t\t\t * If /var/www/file.php/index.php does not exist, but /var/www/file.php does,\n\t\t\t * use /var/www/file.php. This is also what Apache and PHP Dev Server do.\n\t\t\t */\n\t\t\tlet pathToTry = rewrittenRequestUrl.pathname;\n\t\t\twhile (\n\t\t\t\tpathToTry.startsWith('/') &&\n\t\t\t\tpathToTry !== dirname(pathToTry)\n\t\t\t) {\n\t\t\t\tpathToTry = dirname(pathToTry);\n\t\t\t\tconst resolvedPathToTry = joinPaths(this.#DOCROOT, pathToTry);\n\t\t\t\tif (\n\t\t\t\t\tprimaryPhp.isFile(resolvedPathToTry) &&\n\t\t\t\t\t// Only run partial path resolution for PHP files.\n\t\t\t\t\tresolvedPathToTry.endsWith('.php')\n\t\t\t\t) {\n\t\t\t\t\tfsPath = joinPaths(this.#DOCROOT, pathToTry);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!primaryPhp.isFile(fsPath)) {\n\t\t\tconst fileNotFoundAction = this.getFileNotFoundAction(\n\t\t\t\trewrittenRequestUrl.pathname\n\t\t\t);\n\t\t\tswitch (fileNotFoundAction.type) {\n\t\t\t\tcase 'response':\n\t\t\t\t\treturn fileNotFoundAction.response;\n\t\t\t\tcase 'internal-redirect':\n\t\t\t\t\tfsPath = joinPaths(this.#DOCROOT, fileNotFoundAction.uri);\n\t\t\t\t\tbreak;\n\t\t\t\tcase '404':\n\t\t\t\t\treturn PHPResponse.forHttpCode(404);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'Unsupported file-not-found action type: ' +\n\t\t\t\t\t\t\t// Cast because TS asserts the remaining possibility is `never`\n\t\t\t\t\t\t\t`'${\n\t\t\t\t\t\t\t\t(fileNotFoundAction as FileNotFoundAction).type\n\t\t\t\t\t\t\t}'`\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// We need to confirm that the current target file exists because\n\t\t// file-not-found fallback actions may redirect to non-existent files.\n\t\tif (primaryPhp.isFile(fsPath)) {\n\t\t\tif (fsPath.endsWith('.php')) {\n\t\t\t\tconst response = await this.#spawnPHPAndDispatchRequest(\n\t\t\t\t\trequest,\n\t\t\t\t\toriginalRequestUrl,\n\t\t\t\t\trewrittenRequestUrl,\n\t\t\t\t\tfsPath\n\t\t\t\t);\n\n\t\t\t\t/**\n\t\t\t\t * If the response is but the exit code is non-zero, let's rewrite the\n\t\t\t\t * HTTP status code as 500. We're acting as a HTTP server here and\n\t\t\t\t * this behavior is in line with what Nginx and Apache do.\n\t\t\t\t */\n\t\t\t\tif (response.ok() && response.exitCode !== 0) {\n\t\t\t\t\treturn new PHPResponse(\n\t\t\t\t\t\t500,\n\t\t\t\t\t\tresponse.headers,\n\t\t\t\t\t\tresponse.bytes,\n\t\t\t\t\t\tresponse.errors,\n\t\t\t\t\t\tresponse.exitCode\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn response;\n\t\t\t} else {\n\t\t\t\treturn this.#serveStaticFile(primaryPhp, fsPath);\n\t\t\t}\n\t\t} else {\n\t\t\treturn PHPResponse.forHttpCode(404);\n\t\t}\n\t}\n\n\t/**\n\t * Apply the rewrite rules to the original request URL.\n\t *\n\t * @param originalRequestUrl - The original request URL.\n\t * @returns The rewritten request URL.\n\t */\n\t#applyRewriteRules(originalRequestUrl: URL): URL {\n\t\tconst siteRelativePath = removePathPrefix(\n\t\t\tdecodeURIComponent(originalRequestUrl.pathname),\n\t\t\tthis.#PATHNAME\n\t\t);\n\t\tconst rewrittenRequestPath = applyRewriteRules(\n\t\t\tsiteRelativePath,\n\t\t\tthis.rewriteRules\n\t\t);\n\t\tconst rewrittenRequestUrl = new URL(\n\t\t\tjoinPaths(this.#PATHNAME, rewrittenRequestPath),\n\t\t\toriginalRequestUrl.toString()\n\t\t);\n\t\t// Merge the query string parameters from the original request URL.\n\t\tfor (const [key, value] of originalRequestUrl.searchParams.entries()) {\n\t\t\trewrittenRequestUrl.searchParams.append(key, value);\n\t\t}\n\t\treturn rewrittenRequestUrl;\n\t}\n\n\t/**\n\t * Serves a static file from the PHP filesystem.\n\t *\n\t * @param fsPath - Absolute path of the static file to serve.\n\t * @returns The response.\n\t */\n\t#serveStaticFile(php: PHP, fsPath: string): PHPResponse {\n\t\tconst arrayBuffer = php.readFileAsBuffer(fsPath);\n\t\treturn new PHPResponse(\n\t\t\t200,\n\t\t\t{\n\t\t\t\t'content-length': [`${arrayBuffer.byteLength}`],\n\t\t\t\t// @TODO: Infer the content-type from the arrayBuffer instead of the\n\t\t\t\t// file path. The code below won't return the correct mime-type if the\n\t\t\t\t// extension was tampered with.\n\t\t\t\t'content-type': [inferMimeType(fsPath)],\n\t\t\t\t'accept-ranges': ['bytes'],\n\t\t\t\t'cache-control': ['public, max-age=0'],\n\t\t\t},\n\t\t\tarrayBuffer\n\t\t);\n\t}\n\n\t/**\n\t * Spawns a new PHP instance and dispatches a request to it.\n\t */\n\tasync #spawnPHPAndDispatchRequest(\n\t\trequest: PHPRequest,\n\t\toriginalRequestUrl: URL,\n\t\trewrittenRequestUrl: URL,\n\t\tscriptPath: string\n\t): Promise<PHPResponse> {\n\t\tlet spawnedPHP: SpawnedPHP | undefined = undefined;\n\t\ttry {\n\t\t\tspawnedPHP = await this.processManager!.acquirePHPInstance({\n\t\t\t\tconsiderPrimary: true,\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tif (e instanceof MaxPhpInstancesError) {\n\t\t\t\treturn PHPResponse.forHttpCode(502);\n\t\t\t} else {\n\t\t\t\treturn PHPResponse.forHttpCode(500);\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\treturn await this.#dispatchToPHP(\n\t\t\t\tspawnedPHP.php,\n\t\t\t\trequest,\n\t\t\t\toriginalRequestUrl,\n\t\t\t\trewrittenRequestUrl,\n\t\t\t\tscriptPath\n\t\t\t);\n\t\t} finally {\n\t\t\tspawnedPHP.reap();\n\t\t}\n\t}\n\n\t/**\n\t * Runs the requested PHP file with all the request and $_SERVER\n\t * superglobals populated.\n\t *\n\t * @param request - The request.\n\t * @returns The response.\n\t */\n\tasync #dispatchToPHP(\n\t\tphp: PHP,\n\t\trequest: PHPRequest,\n\t\toriginalRequestUrl: URL,\n\t\trewrittenRequestUrl: URL,\n\t\tscriptPath: string\n\t): Promise<PHPResponse> {\n\t\tlet preferredMethod: PHPRunOptions['method'] = 'GET';\n\n\t\tconst headers: Record<string, string> = {\n\t\t\thost: this.#HOST,\n\t\t\t...normalizeHeaders(request.headers || {}),\n\t\t};\n\t\tif (this.#cookieStore) {\n\t\t\theaders['cookie'] = this.#cookieStore.getCookieRequestHeader();\n\t\t}\n\n\t\tlet body = request.body;\n\t\tif (typeof body === 'object' && !(body instanceof Uint8Array)) {\n\t\t\tpreferredMethod = 'POST';\n\t\t\tconst { bytes, contentType } = await encodeAsMultipart(body);\n\t\t\tbody = bytes;\n\t\t\theaders['content-type'] = contentType;\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await php.run({\n\t\t\t\trelativeUri: ensurePathPrefix(\n\t\t\t\t\ttoRelativeUrl(new URL(rewrittenRequestUrl.toString())),\n\t\t\t\t\tthis.#PATHNAME\n\t\t\t\t),\n\t\t\t\tprotocol: this.#PROTOCOL,\n\t\t\t\tmethod: request.method || preferredMethod,\n\t\t\t\t$_SERVER: this.prepare_$_SERVER_superglobal(\n\t\t\t\t\toriginalRequestUrl,\n\t\t\t\t\trewrittenRequestUrl,\n\t\t\t\t\tscriptPath\n\t\t\t\t),\n\t\t\t\tbody,\n\t\t\t\tscriptPath,\n\t\t\t\theaders,\n\t\t\t});\n\t\t\tif (this.#cookieStore) {\n\t\t\t\tthis.#cookieStore.rememberCookiesFromResponseHeaders(\n\t\t\t\t\tresponse.headers\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tconst executionError = error as PHPExecutionFailureError;\n\t\t\tif (executionError?.response) {\n\t\t\t\treturn executionError.response;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Computes the essential $_SERVER entries for a request.\n\t *\n\t * php_wasm.c sets some defaults, assuming it runs as a CLI script.\n\t * This function overrides them with the values correct in the request\n\t * context.\n\t *\n\t * @TODO: Consolidate the $_SERVER setting logic into a single place instead\n\t * of splitting it between the C SAPI and the TypeScript code. The PHP\n\t * class has a `.cli()` method that could take care of the CLI-specific\n\t * $_SERVER values.\n\t *\n\t * Path and URL-related $_SERVER entries are theoretically documented\n\t * at https://www.php.net/manual/en/reserved.variables.server.php,\n\t * but that page is not very helpful in practice. Here are tables derived\n\t * by interacting with PHP servers:\n\t *\n\t * ## PHP Dev Server\n\t *\n\t * Setup:\n\t * – `/home/adam/subdir/script.php` file contains `<?php phpinfo(); ?>`\n\t * – `php -S 127.0.0.1:8041` running in `/home/adam` directory\n\t * – A request is sent to `http://127.0.0.1:8041/subdir/script.php/b.php/c.php`\n\t *\n\t * Results:\n\t *\n\t * $_SERVER['REQUEST_URI'] | `/subdir/script.php/b.php/c.php`\n\t * $_SERVER['SCRIPT_NAME'] | `/subdir/script.php`\n\t * $_SERVER['SCRIPT_FILENAME']| `/home/adam/subdir/script.php`\n\t * $_SERVER['PATH_INFO'] | `/b.php/c.php`\n\t * $_SERVER['PHP_SELF'] | `/subdir/script.php/b.php/c.php`\n\t *\n\t * ## Apache – rewriting rules\n\t *\n\t * Setup:\n\t * – `/var/www/html/subdir/script.php` file contains `<?php phpinfo(); ?>`\n\t * – Apache is listening on port 8041\n\t * – The document root is `/var/www/html`\n\t * – A request is sent to `http://127.0.0.1:8041/api/v1/user/123`\n\t *\n\t * .htaccess file:\n\t *\n\t * ```apache\n\t * RewriteEngine On\n\t * RewriteRule ^api/v1/user/([0-9]+)$ /subdir/script.php?endpoint=user&id=$1 [L,QSA]\n\t * ```\n\t *\n\t * Results:\n\t *\n\t * ```\n\t * $_SERVER['REQUEST_URI'] | /api/v1/user/123\n\t * $_SERVER['SCRIPT_NAME'] | /subdir/script.php\n\t * $_SERVER['SCRIPT_FILENAME'] | /var/www/html/subdir/script.php\n\t * $_SERVER['PATH_INFO'] | (key not set)\n\t * $_SERVER['PHP_SELF'] | /subdir/script.php\n\t * $_SERVER['QUERY_STRING'] | endpoint=user&id=123\n\t * $_SERVER['REDIRECT_STATUS'] | 200\n\t * $_SERVER['REDIRECT_URL'] | /api/v1/user/123\n\t * $_SERVER['REDIRECT_QUERY_STRING'] | endpoint=user&id=123\n\t * === $_GET Variables ===\n\t * $_GET['endpoint'] | user\n\t * $_GET['id'] | 123\n\t * ```\n\t *\n\t * ## Apache – vanilla request\n\t *\n\t * Setup:\n\t * – The same as above.\n\t * – A request sent http://localhost:8041/subdir/script.php?param=value\n\t *\n\t * Results:\n\t *\n\t * ```\n\t * $_SERVER['REQUEST_URI'] | /subdir/script.php?param=value\n\t * $_SERVER['SCRIPT_NAME'] | /subdir/script.php\n\t * $_SERVER['SCRIPT_FILENAME'] | /var/www/html/subdir/script.php\n\t * $_SERVER['PATH_INFO'] | (key not set)\n\t * $_SERVER['PHP_SELF'] | /subdir/script.php\n\t * $_SERVER['REDIRECT_URL'] | (key not set)\n\t * $_SERVER['REDIRECT_STATUS'] | (key not set)\n\t * $_SERVER['QUERY_STRING'] | param=value\n\t * $_SERVER['REQUEST_METHOD'] | GET\n\t * $_SERVER['DOCUMENT_ROOT'] | /var/www/html\n\t *\n\t * === $_GET Variables ===\n\t * $_GET['param'] | value\n\t * ```\n\t */\n\tprivate prepare_$_SERVER_superglobal(\n\t\toriginalRequestUrl: URL,\n\t\trewrittenRequestUrl: URL,\n\t\tresolvedScriptPath: string\n\t): Record<string, string> {\n\t\tconst $_SERVER: Record<string, string> = {\n\t\t\tREMOTE_ADDR: '127.0.0.1',\n\t\t\tDOCUMENT_ROOT: this.#DOCROOT,\n\t\t\tHTTPS: this.#ABSOLUTE_URL.startsWith('https://') ? 'on' : '',\n\t\t};\n\n\t\t/**\n\t\t * REQUEST_URI\n\t\t *\n\t\t * The original path + query string extracted from the requested URL\n\t\t * **before** applying any URL rewriting.\n\t\t */\n\t\t$_SERVER['REQUEST_URI'] =\n\t\t\toriginalRequestUrl.pathname + originalRequestUrl.search;\n\n\t\tif (resolvedScriptPath.startsWith(this.#DOCROOT)) {\n\t\t\t/**\n\t\t\t * SCRIPT_NAME\n\t\t\t *\n\t\t\t * > Contains the current script's path. This is useful for pages\n\t\t\t * > which need to point to themselves.\n\t\t\t *\n\t\t\t * Filesystem path of the script relative to the document root.\n\t\t\t * Note this is a filesystem path so URL rewriting is not applicable here.\n\t\t\t */\n\t\t\t$_SERVER['SCRIPT_NAME'] = resolvedScriptPath.substring(\n\t\t\t\tthis.#DOCROOT.length\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * PHP_SELF – the path sourced from the final **request URL** after the\n\t\t\t * rewrite rules have been applied.\n\t\t\t *\n\t\t\t * php.net documentation is very misleading on this one:\n\t\t\t *\n\t\t\t * > The filename of the currently executing script, relative\n\t\t\t * > to the document root. For instance, $_SERVER['PHP_SELF']\n\t\t\t * > in a script at the address http://example.com/foo/bar.php\n\t\t\t * > would be /foo/bar.php.\n\t\t\t *\n\t\t\t * @see https://www.php.net/manual/en/reserved.variables.server.php#:~:text=PHP_SELF\n\t\t\t *\n\t\t\t * This is not what Apache, nor what the PHP dev server do:\n\t\t\t *\n\t\t\t * – Document Root: /var/www\n\t\t\t * – Script file: /var/www/subdir/script.php\n\t\t\t * – Requesting /subdir/script.php/b.php/c.php\n\t\t\t *\n\t\t\t * $_SERVER['PHP_SELF'] = \"/subdir/script.php/b.php/c.php\"\n\t\t\t *\n\t\t\t * So, in that regard, it is a URL path, not a filesystem path.\n\t\t\t *\n\t\t\t * When URL rewriting is involved, it's the same.\n\t\t\t *\n\t\t\t * Consider this Apache example from above:\n\t\t\t *\n\t\t\t * – Document Root: /var/www/html\n\t\t\t * – Script file: /var/www/html/subdir/script.php\n\t\t\t * – Rewrite rule: ^api/v1/user/([0-9]+)$ /subdir/script.php?endpoint=user&id=$1 [L,QSA]\n\t\t\t * – Requesting /api/v1/user/123\n\t\t\t *\n\t\t\t * $_SERVER['PHP_SELF'] = \"/subdir/script.php\"\n\t\t\t *\n\t\t\t * So, on the face value, this is a filesystem path. However, see\n\t\t\t * what happens if we slightly modify that rewrite rule to:\n\t\t\t *\n\t\t\t * – Rewrite rule: ^api/v1/user/([0-9]+)$ /subdir/script.php/next.php\n\t\t\t * ^^^^^^^^^\n\t\t\t * – Requesting /api/v1/user/123\n\t\t\t *\n\t\t\t * $_SERVER['PHP_SELF'] = \"/subdir/script.php/next.php\"\n\t\t\t *\n\t\t\t * So:\n\t\t\t * * PHP_SELF is not sourced from the filesystem path.\n\t\t\t * * PHP_SELF is sourced from the final request URL after the\n\t\t\t * rewrite rules have been applied.\n\t\t\t */\n\t\t\t$_SERVER['PHP_SELF'] = rewrittenRequestUrl.pathname;\n\n\t\t\t/**\n\t\t\t * PATH_INFO\n\t\t\t *\n\t\t\t * > Contains any client-provided pathname information trailing the actual\n\t\t\t * > script filename but preceding the query string, if available. For instance,\n\t\t\t * > if the current script was accessed via the URI http://www.example.com/php/path_info.php/some/stuff?foo=bar,\n\t\t\t * > then $_SERVER['PATH_INFO'] would contain /some/stuff.\n\t\t\t *\n\t\t\t * This **does not** include the query string.\n\t\t\t *\n\t\t\t * @see https://www.php.net/manual/en/reserved.variables.server.php#:~:text=PATH_INFO\n\t\t\t */\n\t\t\tif ($_SERVER['REQUEST_URI'].startsWith($_SERVER['SCRIPT_NAME'])) {\n\t\t\t\t$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'].substring(\n\t\t\t\t\t$_SERVER['SCRIPT_NAME'].length\n\t\t\t\t);\n\t\t\t\t// Remove the query string if present.\n\t\t\t\tif ($_SERVER['PATH_INFO'].includes('?')) {\n\t\t\t\t\t$_SERVER['PATH_INFO'] = $_SERVER['PATH_INFO'].substring(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t$_SERVER['PATH_INFO'].indexOf('?')\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * QUERY_STRING\n\t\t *\n\t\t * The query string from the original and rewritten request URLs.\n\t\t * Does not include the leading question mark.\n\t\t *\n\t\t * Note it contains all the query parameters from the original\n\t\t * URL merged with the new parameters from the rewritten request URLs.\n\t\t *\n\t\t * Example:\n\t\t * – Original request URL: /pretty/url?foo=bar&page=different-value\n\t\t * – Rewritten request URL: /pretty/url?page=pretty\n\t\t * – QUERY_STRING: page=pretty&foo=bar&page=different-value\n\t\t */\n\t\t$_SERVER['QUERY_STRING'] = rewrittenRequestUrl.search.substring(1);\n\n\t\t/**\n\t\t * There's a few relevant entries we are NOT setting here:\n\t\t *\n\t\t * – SCRIPT_FILENAME: Absolute path to the script file. It is set by\n\t\t * php_wasm.c.\n\t\t * – REDIRECT_STATUS: Apache sets it, but it's optional so we skip it.\n\t\t * – REDIRECT_URL: Apache sets it, but it's optional so we skip it.\n\t\t * – REDIRECT_QUERY_STRING: Apache sets it, but it's optional so we skip it.\n\t\t */\n\t\treturn $_SERVER;\n\t}\n\n\tasync [Symbol.asyncDispose]() {\n\t\tawait this.processManager[Symbol.asyncDispose]();\n\t}\n}\n\n/**\n * Naively infer a file mime type from its path.\n *\n * @todo Infer the mime type based on the file contents.\n * A naive function like this one can be inaccurate\n * and potentially have negative security consequences.\n *\n * @param path - The file path\n * @returns The inferred mime type.\n */\nexport function inferMimeType(path: string): string {\n\tconst extension = path.split('.').pop() as keyof typeof mimeTypes;\n\t// @TODO: Consider not sending a default mime type to let the browser guess\n\treturn mimeTypes[extension] || mimeTypes['_default'];\n}\n\n/**\n * Applies the given rewrite rules to the given path.\n *\n * @param path The path to apply the rules to.\n * @param rules The rules to apply.\n * @returns The path with the rules applied.\n */\nexport function applyRewriteRules(path: string, rules: RewriteRule[]): string {\n\tfor (const rule of rules) {\n\t\tif (new RegExp(rule.match).test(path)) {\n\t\t\tpath = path.replace(rule.match, rule.replacement);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn path;\n}\n","import type { PHP } from './php';\n\nexport interface RotateOptions {\n\tphp: PHP;\n\tcwd?: string;\n\trecreateRuntime: () => Promise<number> | number;\n\tmaxRequests?: number;\n}\n\n/**\n * Configures inline runtime rotation on the provided PHP instance.\n * Returns a cleanup function that disables rotation.\n *\n * @deprecated Use `php.enableRuntimeRotation()` instead.\n */\nexport function rotatePHPRuntime({\n\tphp,\n\trecreateRuntime,\n\tmaxRequests = 400,\n}: RotateOptions) {\n\treturn php.enableRuntimeRotation({\n\t\trecreateRuntime,\n\t\tmaxRequests,\n\t});\n}\n","import { dirname, joinPaths } from '@php-wasm/util';\nimport type { UniversalPHP } from './universal-php';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FileTree\n\textends Record<string, Uint8Array | string | FileTree> {}\n\nexport interface WriteFilesOptions {\n\t/**\n\t * Whether to wipe out the contents of the\n\t * root directory before writing the new files.\n\t */\n\trmRoot?: boolean;\n}\n\n/**\n * Writes multiple files to a specified directory in the Playground\n * filesystem.\n *\n * @example ```ts\n * await writeFiles(php, '/test', {\n * \t'file.txt': 'file',\n * \t'sub/file.txt': 'file',\n * \t'sub1/sub2/file.txt': 'file',\n * });\n * ```\n *\n * @param php\n * @param root\n * @param newFiles\n * @param options\n */\nexport async function writeFiles(\n\tphp: UniversalPHP,\n\troot: string,\n\tnewFiles: FileTree,\n\t{ rmRoot = false }: WriteFilesOptions = {}\n) {\n\tif (rmRoot) {\n\t\tif (await php.isDir(root)) {\n\t\t\tawait php.rmdir(root, { recursive: true });\n\t\t}\n\t}\n\tfor (const [relativePath, content] of Object.entries(newFiles)) {\n\t\tconst filePath = joinPaths(root, relativePath);\n\t\tif (!(await php.fileExists(dirname(filePath)))) {\n\t\t\tawait php.mkdir(dirname(filePath));\n\t\t}\n\t\tif (content instanceof Uint8Array || typeof content === 'string') {\n\t\t\tawait php.writeFile(filePath, content);\n\t\t} else {\n\t\t\tawait writeFiles(php, filePath, content);\n\t\t}\n\t}\n}\n","import type { PHP } from './php';\n\n/**\n * Proxy specific paths to the parent's MEMFS instance.\n * This is useful for sharing the WordPress installation\n * between the parent and child processes.\n */\nexport function proxyFileSystem(\n\tsourceOfTruth: PHP,\n\treplica: PHP,\n\tpaths: string[]\n) {\n\t// We can't just import the symbol from the library because\n\t// Playground CLI is built as ESM and php-wasm-node is built as\n\t// CJS and the imported symbols will different in the production build.\n\tconst __private__symbol = Object.getOwnPropertySymbols(sourceOfTruth)[0];\n\tfor (const path of paths) {\n\t\tif (!replica.fileExists(path)) {\n\t\t\treplica.mkdir(path);\n\t\t}\n\t\tif (!sourceOfTruth.fileExists(path)) {\n\t\t\tsourceOfTruth.mkdir(path);\n\t\t}\n\t\t// @ts-ignore\n\t\treplica[__private__symbol].FS.mount(\n\t\t\t// @ts-ignore\n\t\t\treplica[__private__symbol].PROXYFS,\n\t\t\t{\n\t\t\t\troot: path,\n\t\t\t\t// @ts-ignore\n\t\t\t\tfs: sourceOfTruth[__private__symbol].FS,\n\t\t\t},\n\t\t\tpath\n\t\t);\n\t}\n}\n\n/**\n * Answers whether the given path is to a shared filesystem.\n *\n * @param sourceOfTruth - The PHP instance that is the source of truth.\n * @param path - The path to check.\n * @returns True if the path is to a shared filesystem, false otherwise.\n */\nexport function isPathToSharedFS(sourceOfTruth: PHP, path: string) {\n\t// We can't just import the symbol from the library because\n\t// Playground CLI is built as ESM and php-wasm-node is built as\n\t// CJS and the imported symbols will different in the production build.\n\tconst __private__symbol = Object.getOwnPropertySymbols(sourceOfTruth)[0];\n\n\t// @ts-ignore\n\tconst FS = sourceOfTruth[__private__symbol].FS;\n\n\tconst fsResult = FS.lookupPath(path, { noent_okay: true });\n\treturn fsResult?.node?.isSharedFS ?? false;\n}\n","import { createSpawnHandler } from '@php-wasm/util';\nimport type { PHPProcessManager } from './php-process-manager';\n\n/**\n * An isomorphic proc_open() handler that implements typical shell in TypeScript\n * without relying on a server runtime. It can be used in the browser and Node.js\n * alike whenever you need to spawn a PHP subprocess, query the terminal size, etc.\n * It is open for future expansion if more shell or busybox calls are needed, but\n * advanced shell features such as piping, stream redirection etc. are outside of\n * the scope of this minimal handler. If they become vital at any point, let's\n * explore bringing in an actual shell implementation or at least a proper command\n * parser.\n */\nexport function sandboxedSpawnHandlerFactory(\n\tprocessManager: PHPProcessManager\n) {\n\treturn createSpawnHandler(async function (args, processApi, options) {\n\t\tprocessApi.notifySpawn();\n\t\tif (args[0] === 'exec') {\n\t\t\targs.shift();\n\t\t}\n\n\t\tif (args[0].endsWith('.php') || args[0].endsWith('.phar')) {\n\t\t\targs.unshift('php');\n\t\t}\n\n\t\tconst binaryName = args[0].split('/').pop();\n\n\t\t// Mock programs required by wp-cli:\n\t\tif (\n\t\t\targs[0] === '/usr/bin/env' &&\n\t\t\targs[1] === 'stty' &&\n\t\t\targs[2] === 'size'\n\t\t) {\n\t\t\t// These numbers are hardcoded because this\n\t\t\t// spawnHandler is transmitted as a string to\n\t\t\t// the PHP backend and has no access to local\n\t\t\t// scope. It would be nice to find a way to\n\t\t\t// transfer / proxy a live object instead.\n\t\t\t// @TODO: Do not hardcode this\n\t\t\tprocessApi.stdout(`18 140`);\n\t\t\tprocessApi.exit(0);\n\t\t} else if (binaryName === 'tput' && args[1] === 'cols') {\n\t\t\tprocessApi.stdout(`140`);\n\t\t\tprocessApi.exit(0);\n\t\t} else if (binaryName === 'less') {\n\t\t\tprocessApi.on('stdin', (data) => {\n\t\t\t\tprocessApi.stdout(data);\n\t\t\t});\n\t\t\t// Exit after the stdin stream is exhausted.\n\t\t\tawait new Promise((resolve) => {\n\t\t\t\tprocessApi.childProcess.stdin.on('finish', () => {\n\t\t\t\t\tresolve(true);\n\t\t\t\t});\n\t\t\t});\n\t\t\tprocessApi.exit(0);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!['php', 'ls', 'pwd'].includes(binaryName ?? '')) {\n\t\t\t// 127 is the exit code \"for command not found\".\n\t\t\tprocessApi.exit(127);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { php, reap } = await processManager.acquirePHPInstance({\n\t\t\tconsiderPrimary: false,\n\t\t});\n\n\t\ttry {\n\t\t\tif (options.cwd) {\n\t\t\t\tphp.chdir(options.cwd as string);\n\t\t\t}\n\n\t\t\tconst cwd = php.cwd();\n\t\t\tswitch (binaryName) {\n\t\t\t\tcase 'php': {\n\t\t\t\t\t// Figure out more about setting env, putenv(), etc.\n\t\t\t\t\tconst result = await php.cli(args, {\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\t...options.env,\n\t\t\t\t\t\t\tSCRIPT_PATH: args[1],\n\t\t\t\t\t\t\t// Set SHELL_PIPE to 0 to ensure WP-CLI formats\n\t\t\t\t\t\t\t// the output as ASCII tables.\n\t\t\t\t\t\t\t// @see https://github.com/wp-cli/wp-cli/issues/1102\n\t\t\t\t\t\t\tSHELL_PIPE: '0',\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tresult.stdout.pipeTo(\n\t\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\t\tprocessApi.stdout(chunk as any as ArrayBuffer);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tresult.stderr.pipeTo(\n\t\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\t\tprocessApi.stderr(chunk as any as ArrayBuffer);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprocessApi.exit(await result.exitCode);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'ls': {\n\t\t\t\t\tconst files = php.listFiles(args[1] ?? cwd);\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tprocessApi.stdout(file + '\\n');\n\t\t\t\t\t}\n\t\t\t\t\t// Technical limitation of subprocesses – we need to\n\t\t\t\t\t// wait before exiting to give consumer a chance to read\n\t\t\t\t\t// the output.\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\t\t\t\t\tprocessApi.exit(0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'pwd': {\n\t\t\t\t\tprocessApi.stdout(cwd + '\\n');\n\t\t\t\t\t// Technical limitation of subprocesses – we need to\n\t\t\t\t\t// wait before exiting to give consumer a chance to read\n\t\t\t\t\t// the output.\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\t\t\t\t\tprocessApi.exit(0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\t// An exception here means the PHP runtime has crashed.\n\t\t\tprocessApi.exit(1);\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\treap();\n\t\t}\n\t});\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-misused-new */\n/* eslint-disable @typescript-eslint/no-empty-object-type */\nimport type { MessagePort as NodeMessagePort } from 'worker_threads';\n\n/**\n * Comlink library protocol extension to use synchronous messaging.\n *\n * Debugging Asyncify is too much of a burden. This extension enables exchanging\n * messages between threads synchronously so that we don't need to rely on Asyncify.\n *\n * Upsides:\n *\n * * Saves dozens-to-hundreds of hours on debugging Asyncify issues\n * * Increased reliability\n * * Useful stack traces when errors do happen.\n *\n * Downsides:\n *\n * * Fragmentation: Both synchronous and asynchronous handlers exist to get the best our of both\n * Asyncify and JSPI. * Node.js-only: This extension does not implement a Safari-friendly\n * transport. SharedArrayBuffer is an option, but\n * it requires more restrictive CORP+COEP headers which breaks, e.g., YouTube\n * embeds. Synchronous XHR might work if we really need Safari support for one of\n * the new asynchronous features, but other than that let's just skip adding new\n * asynchronous WASM features to Safari until WebKit supports stack switching.\n * * Message passing between workers is slow. Avoid using synchronous messaging for syscalls that\n * are invoked frequently and\n * handled asynchronously in the same worker.\n *\n * @see https://github.com/adamziel/js-synchronous-messaging for additional ideas.\n * @see https://github.com/WordPress/wordpress-playground/blob/9a9262cc62cc161d220a9992706b9ed2817f2eb5/packages/docs/site/docs/developers/23-architecture/07-wasm-asyncify.md\n */\ninterface SyncMessage {\n\t/** original Comlink envelope */\n\tid?: string;\n\ttype: MessageType;\n\t/** existing Comlink fields … */\n\t[k: string]: any;\n\t/** new part that carries the latch */\n\tnotifyBuffer?: SharedArrayBuffer;\n}\n\ninterface SyncTransport {\n\tafterResponseSent(ev: MessageEvent): void;\n\tsend(\n\t\tep: IsomorphicMessagePort,\n\t\tmsg: Omit<SyncMessage, 'id' | 'notifyBuffer'>,\n\t\ttransferables?: Transferable[]\n\t): WireValue;\n}\n\nexport function exposeSync(\n\tobj: any,\n\tep: Endpoint,\n\ttransport: SyncTransport,\n\tallowedOrigins: (string | RegExp)[] = ['*']\n) {\n\treturn expose(obj, ep, allowedOrigins, transport.afterResponseSent);\n}\n\n//////////////////////////////\n// 3. Consumer side //\n//////////////////////////////\n\nfunction createSyncProxy<T>(\n\tep: IsomorphicMessagePort,\n\tpath: (string | number | symbol)[] = [],\n\ttransport: SyncTransport\n): T {\n\treturn new Proxy(() => {}, {\n\t\tget(_t, prop) {\n\t\t\tif (prop === 'then') {\n\t\t\t\t// allow await‑usage without deadlocking\n\t\t\t\tif (!path.length)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tthen: (_: any, res: any) =>\n\t\t\t\t\t\t\tres(createSyncProxy(ep, [], transport)),\n\t\t\t\t\t};\n\t\t\t}\n\t\t\treturn createSyncProxy(ep, [...path, prop], transport);\n\t\t},\n\n\t\tset(_t, prop, value) {\n\t\t\tconst [v, xfer] = toWireValue(value);\n\t\t\ttransport.send(\n\t\t\t\tep,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.SET,\n\t\t\t\t\tpath: [...path, prop].map(String),\n\t\t\t\t\tvalue: v,\n\t\t\t\t},\n\t\t\t\txfer\n\t\t\t);\n\t\t\treturn true;\n\t\t},\n\n\t\tapply(_t, _thisArg, rawArgs) {\n\t\t\t// Special cases\n\t\t\tconst last = path.at(-1);\n\t\t\tif (last === 'bind')\n\t\t\t\treturn createSyncProxy(ep, path.slice(0, -1), transport);\n\n\t\t\tconst [argList, xfer] = processArguments(rawArgs);\n\t\t\tconst wire = transport.send(\n\t\t\t\tep,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.APPLY,\n\t\t\t\t\tpath: path.map(String),\n\t\t\t\t\targumentList: argList,\n\t\t\t\t},\n\t\t\t\txfer\n\t\t\t);\n\n\t\t\treturn fromWireValue(wire);\n\t\t},\n\n\t\tconstruct(_t, rawArgs) {\n\t\t\tconst [argList, xfer] = processArguments(rawArgs);\n\t\t\tconst wire = transport.send(\n\t\t\t\tep,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.CONSTRUCT,\n\t\t\t\t\tpath: path.map(String),\n\t\t\t\t\targumentList: argList,\n\t\t\t\t},\n\t\t\t\txfer\n\t\t\t);\n\t\t\treturn fromWireValue(wire);\n\t\t},\n\t}) as unknown as T;\n}\n\nexport function wrapSync<T>(\n\tep: IsomorphicMessagePort,\n\ttransport: SyncTransport\n): T {\n\treturn createSyncProxy<T>(ep, [], transport);\n}\n\n/// Transport ///\n\nexport type IsomorphicMessagePort = MessagePort | NodeMessagePort;\n\nexport class NodeSABSyncReceiveMessageTransport {\n\tprivate static receiveMessageOnPort: any;\n\n\tstatic async create() {\n\t\tif (!NodeSABSyncReceiveMessageTransport.receiveMessageOnPort) {\n\t\t\ttry {\n\t\t\t\tNodeSABSyncReceiveMessageTransport.receiveMessageOnPort =\n\t\t\t\t\trequire('worker_threads').receiveMessageOnPort;\n\t\t\t} catch {\n\t\t\t\tNodeSABSyncReceiveMessageTransport.receiveMessageOnPort =\n\t\t\t\t\tawait import('worker_threads').then(\n\t\t\t\t\t\t(m) => m.receiveMessageOnPort\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn new NodeSABSyncReceiveMessageTransport();\n\t}\n\n\tprivate constructor() {}\n\n\tafterResponseSent(ev: MessageEvent) {\n\t\tconst { notifyBuffer } = ev.data as SyncMessage;\n\t\tif (notifyBuffer) {\n\t\t\tconst view = new Int32Array(notifyBuffer);\n\t\t\tview[0] = 1;\n\t\t\tAtomics.notify(view, 0);\n\t\t}\n\t}\n\tsend(\n\t\tep: IsomorphicMessagePort,\n\t\tmsg: Omit<SyncMessage, 'id' | 'notifyBuffer'>,\n\t\ttransferables?: Transferable[]\n\t): WireValue {\n\t\t// SharedArrayBuffer = one 32‑bit cell that starts at 0.\n\t\t// The other worker will set this to 1 when it has sent the response.\n\t\tconst latch = new SharedArrayBuffer(4);\n\t\tconst view = new Int32Array(latch);\n\t\tview[0] = 0;\n\n\t\tconst id = generateUUID();\n\t\tep.postMessage(\n\t\t\t{ ...msg, id, notifyBuffer: latch },\n\t\t\ttransferables as any\n\t\t);\n\n\t\t// Synchronous pull; Node.js-only. Browsers don't support receiveMessageOnPort.\n\t\tconst timeoutMs = 5000;\n\t\tconst result = Atomics.wait(view, 0, 0, timeoutMs);\n\t\tif (result === 'timed-out') {\n\t\t\tthrow new Error('Timeout waiting for response');\n\t\t}\n\t\twhile (true) {\n\t\t\tconst res =\n\t\t\t\tNodeSABSyncReceiveMessageTransport.receiveMessageOnPort(ep);\n\t\t\tif (res.message?.id === id) {\n\t\t\t\treturn res.message;\n\t\t\t} else if (!res) {\n\t\t\t\tthrow new Error('No response received');\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Original, unmodified Comlink library from Google:\n *\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const proxyMarker = Symbol('Comlink.proxy');\nexport const createEndpoint = Symbol('Comlink.endpoint');\nexport const releaseProxy = Symbol('Comlink.releaseProxy');\nexport const finalizer = Symbol('Comlink.finalizer');\n\nconst throwMarker = Symbol('Comlink.thrown');\n\n/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface EventSource {\n\taddEventListener(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n\n\tremoveEventListener(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n}\n\nexport interface PostMessageWithOrigin {\n\tpostMessage(\n\t\tmessage: any,\n\t\ttargetOrigin: string,\n\t\ttransfer?: Transferable[]\n\t): void;\n}\n\nexport interface Endpoint extends EventSource {\n\tpostMessage(message: any, transfer?: Transferable[]): void;\n\n\tstart?: () => void;\n}\n\nexport const WireValueType = {\n\tRAW: 'RAW',\n\tPROXY: 'PROXY',\n\tTHROW: 'THROW',\n\tHANDLER: 'HANDLER',\n} as const;\n\nexport type WireValueType = typeof WireValueType;\n\nexport interface RawWireValue {\n\tid?: string;\n\ttype: WireValueType['RAW'];\n\tvalue: any;\n}\n\nexport interface HandlerWireValue {\n\tid?: string;\n\ttype: WireValueType['HANDLER'];\n\tname: string;\n\tvalue: unknown;\n}\n\nexport type WireValue = RawWireValue | HandlerWireValue;\n\nexport type MessageID = string;\n\nexport const MessageType = {\n\tGET: 'GET',\n\tSET: 'SET',\n\tAPPLY: 'APPLY',\n\tCONSTRUCT: 'CONSTRUCT',\n\tENDPOINT: 'ENDPOINT',\n\tRELEASE: 'RELEASE',\n} as const;\nexport type MessageType = typeof MessageType;\n\nexport interface GetMessage {\n\tid?: MessageID;\n\ttype: MessageType['GET'];\n\tpath: string[];\n}\n\nexport interface SetMessage {\n\tid?: MessageID;\n\ttype: MessageType['SET'];\n\tpath: string[];\n\tvalue: WireValue;\n}\n\nexport interface ApplyMessage {\n\tid?: MessageID;\n\ttype: MessageType['APPLY'];\n\tpath: string[];\n\targumentList: WireValue[];\n}\n\nexport interface ConstructMessage {\n\tid?: MessageID;\n\ttype: MessageType['CONSTRUCT'];\n\tpath: string[];\n\targumentList: WireValue[];\n}\n\nexport interface EndpointMessage {\n\tid?: MessageID;\n\ttype: MessageType['ENDPOINT'];\n}\n\nexport interface ReleaseMessage {\n\tid?: MessageID;\n\ttype: MessageType['RELEASE'];\n}\n\nexport type Message =\n\t| GetMessage\n\t| SetMessage\n\t| ApplyMessage\n\t| ConstructMessage\n\t| EndpointMessage\n\t| ReleaseMessage;\n\n/**\n * Interface of values that were marked to be proxied with `comlink.proxy()`.\n * Can also be implemented by classes.\n */\nexport interface ProxyMarked {\n\t[proxyMarker]: true;\n}\n\n/**\n * Takes a type and wraps it in a Promise, if it not already is one.\n * This is to avoid `Promise<Promise<T>>`.\n *\n * This is the inverse of `Unpromisify<T>`.\n */\ntype Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;\n/**\n * Takes a type that may be Promise and unwraps the Promise type.\n * If `P` is not a Promise, it returns `P`.\n *\n * This is the inverse of `Promisify<T>`.\n */\ntype Unpromisify<P> = P extends Promise<infer T> ? T : P;\n\n/**\n * Takes the raw type of a remote property and returns the type that is visible to the local thread\n * on the proxy.\n *\n * Note: This needs to be its own type alias, otherwise it will not distribute over unions.\n * See https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types\n */\ntype RemoteProperty<T> =\n\t// If the value is a method, comlink will proxy it automatically.\n\t// Objects are only proxied if they are marked to be proxied.\n\t// Otherwise, the property is converted to a Promise that resolves the cloned value.\n\tT extends Function | ProxyMarked ? Remote<T> : Promisify<T>;\n\n/**\n * Takes the raw type of a property as a remote thread would see it through a proxy (e.g. when\n * passed in as a function argument) and returns the type that the local thread has to supply.\n *\n * This is the inverse of `RemoteProperty<T>`.\n *\n * Note: This needs to be its own type alias, otherwise it will not distribute over unions. See\n * https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types\n */\ntype LocalProperty<T> = T extends Function | ProxyMarked\n\t? Local<T>\n\t: Unpromisify<T>;\n\n/**\n * Proxies `T` if it is a `ProxyMarked`, clones it otherwise (as handled by structured cloning and\n * transfer handlers).\n */\nexport type ProxyOrClone<T> = T extends ProxyMarked ? Remote<T> : T;\n/**\n * Inverse of `ProxyOrClone<T>`.\n */\nexport type UnproxyOrClone<T> = T extends RemoteObject<ProxyMarked>\n\t? Local<T>\n\t: T;\n\n/**\n * Takes the raw type of a remote object in the other thread and returns the type as it is visible\n * to the local thread when proxied with `Comlink.proxy()`.\n *\n * This does not handle call signatures, which is handled by the more general `Remote<T>` type.\n *\n * @template T The raw type of a remote object as seen in the other thread.\n */\nexport type RemoteObject<T> = { [P in keyof T]: RemoteProperty<T[P]> };\n/**\n * Takes the type of an object as a remote thread would see it through a proxy (e.g. when passed in\n * as a function argument) and returns the type that the local thread has to supply.\n *\n * This does not handle call signatures, which is handled by the more general `Local<T>` type.\n *\n * This is the inverse of `RemoteObject<T>`.\n *\n * @template T The type of a proxied object.\n */\nexport type LocalObject<T> = { [P in keyof T]: LocalProperty<T[P]> };\n\n/**\n * Additional special comlink methods available on each proxy returned by `Comlink.wrap()`.\n */\nexport interface ProxyMethods {\n\t[createEndpoint]: () => Promise<MessagePort>;\n\t[releaseProxy]: () => void;\n}\n\n/**\n * Takes the raw type of a remote object, function or class in the other thread and returns the\n * type as it is visible to the local thread from the proxy return value of `Comlink.wrap()` or\n * `Comlink.proxy()`.\n */\nexport type Remote<T> =\n\t// Handle properties\n\tRemoteObject<T> &\n\t\t// Handle call signature (if present)\n\t\t(T extends (...args: infer TArguments) => infer TReturn\n\t\t\t? (\n\t\t\t\t\t...args: {\n\t\t\t\t\t\t[I in keyof TArguments]: UnproxyOrClone<TArguments[I]>;\n\t\t\t\t\t}\n\t\t\t ) => Promisify<ProxyOrClone<Unpromisify<TReturn>>>\n\t\t\t: unknown) &\n\t\t// Handle construct signature (if present)\n\t\t// The return of construct signatures is always proxied (whether marked or not)\n\t\t(T extends { new (...args: infer TArguments): infer TInstance }\n\t\t\t? {\n\t\t\t\t\tnew (\n\t\t\t\t\t\t...args: {\n\t\t\t\t\t\t\t[I in keyof TArguments]: UnproxyOrClone<\n\t\t\t\t\t\t\t\tTArguments[I]\n\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t}\n\t\t\t\t\t): Promisify<Remote<TInstance>>;\n\t\t\t }\n\t\t\t: unknown) &\n\t\t// Include additional special comlink methods available on the proxy.\n\t\tProxyMethods;\n\n/**\n * Expresses that a type can be either a sync or async.\n */\ntype MaybePromise<T> = Promise<T> | T;\n\n/**\n * Takes the raw type of a remote object, function or class as a remote thread would see it through\n * a proxy (e.g. when passed in as a function argument) and returns the type the local thread has\n * to supply.\n *\n * This is the inverse of `Remote<T>`. It takes a `Remote<T>` and returns its original input `T`.\n */\nexport type Local<T> =\n\t// Omit the special proxy methods (they don't need to be supplied, comlink adds them)\n\tOmit<LocalObject<T>, keyof ProxyMethods> &\n\t\t// Handle call signatures (if present)\n\t\t(T extends (...args: infer TArguments) => infer TReturn\n\t\t\t? (\n\t\t\t\t\t...args: {\n\t\t\t\t\t\t[I in keyof TArguments]: ProxyOrClone<TArguments[I]>;\n\t\t\t\t\t}\n\t\t\t ) => // The raw function could either be sync or async, but is always proxied automatically\n\t\t\t MaybePromise<UnproxyOrClone<Unpromisify<TReturn>>>\n\t\t\t: unknown) &\n\t\t// Handle construct signature (if present)\n\t\t// The return of construct signatures is always proxied (whether marked or not)\n\t\t(T extends { new (...args: infer TArguments): infer TInstance }\n\t\t\t? {\n\t\t\t\t\tnew (\n\t\t\t\t\t\t...args: {\n\t\t\t\t\t\t\t[I in keyof TArguments]: ProxyOrClone<\n\t\t\t\t\t\t\t\tTArguments[I]\n\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t}\n\t\t\t\t\t): // The raw constructor could either be sync or async, but is always proxied automatically\n\t\t\t\t\tMaybePromise<Local<Unpromisify<TInstance>>>;\n\t\t\t }\n\t\t\t: unknown);\n\nconst isObject = (val: unknown): val is object =>\n\t(typeof val === 'object' && val !== null) || typeof val === 'function';\n\n/**\n * Customizes the serialization of certain values as determined by `canHandle()`.\n *\n * @template T The input type being handled by this transfer handler.\n * @template S The serialized type sent over the wire.\n */\nexport interface TransferHandler<T, S> {\n\t/**\n\t * Gets called for every value to determine whether this transfer handler\n\t * should serialize the value, which includes checking that it is of the right\n\t * type (but can perform checks beyond that as well).\n\t */\n\tcanHandle(value: unknown): value is T;\n\n\t/**\n\t * Gets called with the value if `canHandle()` returned `true` to produce a\n\t * value that can be sent in a message, consisting of structured-cloneable\n\t * values and/or transferrable objects.\n\t */\n\tserialize(value: T): [S, Transferable[]];\n\n\t/**\n\t * Gets called to deserialize an incoming value that was serialized in the\n\t * other thread with this transfer handler (known through the name it was\n\t * registered under).\n\t */\n\tdeserialize(value: S): T;\n}\n\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler: TransferHandler<object, MessagePort> = {\n\tcanHandle: (val): val is ProxyMarked =>\n\t\tisObject(val) && (val as ProxyMarked)[proxyMarker],\n\tserialize(obj) {\n\t\tconst { port1, port2 } = new MessageChannel();\n\t\texpose(obj, port1);\n\t\treturn [port2, [port2]];\n\t},\n\tdeserialize(port) {\n\t\tport.start();\n\t\treturn wrap(port);\n\t},\n};\n\ninterface ThrownValue {\n\t[throwMarker]: unknown; // just needs to be present\n\tvalue: unknown;\n}\ntype SerializedThrownValue =\n\t| { isError: true; value: Error }\n\t| { isError: false; value: unknown };\ntype PendingListenersMap = Map<\n\tstring,\n\t(value: WireValue | PromiseLike<WireValue>) => void\n>;\n\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler: TransferHandler<\n\tThrownValue,\n\tSerializedThrownValue\n> = {\n\tcanHandle: (value): value is ThrownValue =>\n\t\tisObject(value) && throwMarker in value,\n\tserialize({ value }) {\n\t\tlet serialized: SerializedThrownValue;\n\t\tif (value instanceof Error) {\n\t\t\tserialized = {\n\t\t\t\tisError: true,\n\t\t\t\tvalue: {\n\t\t\t\t\tmessage: value.message,\n\t\t\t\t\tname: value.name,\n\t\t\t\t\tstack: value.stack,\n\t\t\t\t},\n\t\t\t};\n\t\t} else {\n\t\t\tserialized = { isError: false, value };\n\t\t}\n\t\treturn [serialized, []];\n\t},\n\tdeserialize(serialized) {\n\t\tif (serialized.isError) {\n\t\t\tthrow Object.assign(\n\t\t\t\tnew Error(serialized.value.message),\n\t\t\t\tserialized.value\n\t\t\t);\n\t\t}\n\t\tthrow serialized.value;\n\t},\n};\n\n/**\n * Allows customizing the serialization of certain values.\n */\nexport const transferHandlers = new Map<\n\tstring,\n\tTransferHandler<unknown, unknown>\n>([\n\t['proxy', proxyTransferHandler],\n\t['throw', throwTransferHandler],\n]);\n\nfunction isAllowedOrigin(\n\tallowedOrigins: (string | RegExp)[],\n\torigin: string\n): boolean {\n\tfor (const allowedOrigin of allowedOrigins) {\n\t\tif (origin === allowedOrigin || allowedOrigin === '*') {\n\t\t\treturn true;\n\t\t}\n\t\tif (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function expose(\n\tobj: any,\n\tep: Endpoint = globalThis as any,\n\tallowedOrigins: (string | RegExp)[] = ['*'],\n\tafterResponseSent?: (ev: MessageEvent) => void\n) {\n\tep.addEventListener('message', function callback(ev: MessageEvent) {\n\t\tif (!ev || !ev.data) {\n\t\t\treturn;\n\t\t}\n\t\tif (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n\t\t\treturn;\n\t\t}\n\t\tconst { id, type, path } = {\n\t\t\tpath: [] as string[],\n\t\t\t...(ev.data as Message),\n\t\t};\n\t\tconst argumentList = (ev.data.argumentList || []).map(fromWireValue);\n\t\tlet returnValue;\n\t\ttry {\n\t\t\tconst parent = path\n\t\t\t\t.slice(0, -1)\n\t\t\t\t.reduce((obj, prop) => obj[prop], obj);\n\t\t\tconst rawValue = path.reduce((obj, prop) => obj[prop], obj);\n\t\t\tswitch (type) {\n\t\t\t\tcase MessageType.GET:\n\t\t\t\t\t{\n\t\t\t\t\t\treturnValue = rawValue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.SET:\n\t\t\t\t\t{\n\t\t\t\t\t\tparent[path.slice(-1)[0]] = fromWireValue(\n\t\t\t\t\t\t\tev.data.value\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturnValue = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.APPLY:\n\t\t\t\t\t{\n\t\t\t\t\t\treturnValue = rawValue.apply(parent, argumentList);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.CONSTRUCT:\n\t\t\t\t\t{\n\t\t\t\t\t\tconst value = new rawValue(...argumentList);\n\t\t\t\t\t\treturnValue = proxy(value);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.ENDPOINT:\n\t\t\t\t\t{\n\t\t\t\t\t\tconst { port1, port2 } = new MessageChannel();\n\t\t\t\t\t\texpose(obj, port2);\n\t\t\t\t\t\treturnValue = transfer(port1, [port1]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.RELEASE:\n\t\t\t\t\t{\n\t\t\t\t\t\treturnValue = undefined;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} catch (value) {\n\t\t\treturnValue = { value, [throwMarker]: 0 };\n\t\t}\n\t\tPromise.resolve(returnValue)\n\t\t\t.catch((value) => {\n\t\t\t\treturn { value, [throwMarker]: 0 };\n\t\t\t})\n\t\t\t.then((returnValue) => {\n\t\t\t\tconst [wireValue, transferables] = toWireValue(returnValue);\n\t\t\t\tep.postMessage({ ...wireValue, id }, transferables);\n\t\t\t\tif (type === MessageType.RELEASE) {\n\t\t\t\t\t// detach and deactive after sending release response above.\n\t\t\t\t\tep.removeEventListener('message', callback as any);\n\t\t\t\t\tcloseEndPoint(ep);\n\t\t\t\t\tif (\n\t\t\t\t\t\tfinalizer in obj &&\n\t\t\t\t\t\ttypeof obj[finalizer] === 'function'\n\t\t\t\t\t) {\n\t\t\t\t\t\tobj[finalizer]();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// Send Serialization Error To Caller\n\t\t\t\tconst [wireValue, transferables] = toWireValue({\n\t\t\t\t\tvalue: new TypeError('Unserializable return value'),\n\t\t\t\t\t[throwMarker]: 0,\n\t\t\t\t});\n\t\t\t\tep.postMessage({ ...wireValue, id }, transferables);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tafterResponseSent?.(ev);\n\t\t\t});\n\t} as any);\n\tif (ep.start) {\n\t\tep.start();\n\t}\n}\n\nfunction isMessagePort(endpoint: Endpoint): endpoint is MessagePort {\n\treturn endpoint.constructor.name === 'MessagePort';\n}\n\nfunction closeEndPoint(endpoint: Endpoint) {\n\tif (isMessagePort(endpoint)) endpoint.close();\n}\n\nexport function wrap<T>(ep: Endpoint, target?: any): Remote<T> {\n\tconst pendingListeners: PendingListenersMap = new Map();\n\n\tep.addEventListener('message', function handleMessage(ev: Event) {\n\t\tconst { data } = ev as MessageEvent;\n\t\tif (!data || !data.id) {\n\t\t\treturn;\n\t\t}\n\t\tconst resolver = pendingListeners.get(data.id);\n\t\tif (!resolver) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tresolver(data);\n\t\t} finally {\n\t\t\tpendingListeners.delete(data.id);\n\t\t}\n\t});\n\n\treturn createProxy<T>(ep, pendingListeners, [], target) as any;\n}\n\nfunction throwIfProxyReleased(isReleased: boolean) {\n\tif (isReleased) {\n\t\tthrow new Error('Proxy has been released and is not useable');\n\t}\n}\n\nfunction releaseEndpoint(ep: Endpoint) {\n\treturn requestResponseMessage(ep, new Map(), {\n\t\ttype: MessageType.RELEASE,\n\t}).then(() => {\n\t\tcloseEndPoint(ep);\n\t});\n}\n\ninterface FinalizationRegistry<T> {\n\t// @ts-ignore\n\tnew (cb: (heldValue: T) => void): FinalizationRegistry<T>;\n\tregister(\n\t\tweakItem: object,\n\t\theldValue: T,\n\t\tunregisterToken?: object | undefined\n\t): void;\n\tunregister(unregisterToken: object): void;\n}\ndeclare const FinalizationRegistry: FinalizationRegistry<Endpoint>;\n\nconst proxyCounter = new WeakMap<Endpoint, number>();\nconst proxyFinalizers =\n\t'FinalizationRegistry' in globalThis &&\n\tnew FinalizationRegistry((ep: Endpoint) => {\n\t\tconst newCount = (proxyCounter.get(ep) || 0) - 1;\n\t\tproxyCounter.set(ep, newCount);\n\t\tif (newCount === 0) {\n\t\t\treleaseEndpoint(ep);\n\t\t}\n\t});\n\nfunction registerProxy(proxy: object, ep: Endpoint) {\n\tconst newCount = (proxyCounter.get(ep) || 0) + 1;\n\tproxyCounter.set(ep, newCount);\n\tif (proxyFinalizers) {\n\t\tproxyFinalizers.register(proxy, ep, proxy);\n\t}\n}\n\nfunction unregisterProxy(proxy: object) {\n\tif (proxyFinalizers) {\n\t\tproxyFinalizers.unregister(proxy);\n\t}\n}\n\nfunction createProxy<T>(\n\tep: Endpoint,\n\tpendingListeners: PendingListenersMap,\n\tpath: (string | number | symbol)[] = [],\n\ttarget: object = function () {}\n): Remote<T> {\n\tlet isProxyReleased = false;\n\tconst proxy = new Proxy(target, {\n\t\tget(_target, prop) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\tif (prop === releaseProxy) {\n\t\t\t\treturn () => {\n\t\t\t\t\tunregisterProxy(proxy);\n\t\t\t\t\treleaseEndpoint(ep);\n\t\t\t\t\tpendingListeners.clear();\n\t\t\t\t\tisProxyReleased = true;\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (prop === 'then') {\n\t\t\t\tif (path.length === 0) {\n\t\t\t\t\treturn { then: () => proxy };\n\t\t\t\t}\n\t\t\t\tconst r = requestResponseMessage(ep, pendingListeners, {\n\t\t\t\t\ttype: MessageType.GET,\n\t\t\t\t\tpath: path.map((p) => p.toString()),\n\t\t\t\t}).then(fromWireValue);\n\t\t\t\treturn r.then.bind(r);\n\t\t\t}\n\t\t\treturn createProxy(ep, pendingListeners, [...path, prop]);\n\t\t},\n\t\tset(_target, prop, rawValue) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\t// FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n\t\t\t// boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n\t\t\tconst [value, transferables] = toWireValue(rawValue);\n\t\t\treturn requestResponseMessage(\n\t\t\t\tep,\n\t\t\t\tpendingListeners,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.SET,\n\t\t\t\t\tpath: [...path, prop].map((p) => p.toString()),\n\t\t\t\t\tvalue,\n\t\t\t\t},\n\t\t\t\ttransferables\n\t\t\t).then(fromWireValue) as any;\n\t\t},\n\t\tapply(_target, _thisArg, rawArgumentList) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\tconst last = path[path.length - 1];\n\t\t\tif ((last as any) === createEndpoint) {\n\t\t\t\treturn requestResponseMessage(ep, pendingListeners, {\n\t\t\t\t\ttype: MessageType.ENDPOINT,\n\t\t\t\t}).then(fromWireValue);\n\t\t\t}\n\t\t\t// We just pretend that `bind()` didn’t happen.\n\t\t\tif (last === 'bind') {\n\t\t\t\treturn createProxy(ep, pendingListeners, path.slice(0, -1));\n\t\t\t}\n\t\t\tconst [argumentList, transferables] =\n\t\t\t\tprocessArguments(rawArgumentList);\n\t\t\treturn requestResponseMessage(\n\t\t\t\tep,\n\t\t\t\tpendingListeners,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.APPLY,\n\t\t\t\t\tpath: path.map((p) => p.toString()),\n\t\t\t\t\targumentList,\n\t\t\t\t},\n\t\t\t\ttransferables\n\t\t\t).then(fromWireValue);\n\t\t},\n\t\tconstruct(_target, rawArgumentList) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\tconst [argumentList, transferables] =\n\t\t\t\tprocessArguments(rawArgumentList);\n\t\t\treturn requestResponseMessage(\n\t\t\t\tep,\n\t\t\t\tpendingListeners,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.CONSTRUCT,\n\t\t\t\t\tpath: path.map((p) => p.toString()),\n\t\t\t\t\targumentList,\n\t\t\t\t},\n\t\t\t\ttransferables\n\t\t\t).then(fromWireValue);\n\t\t},\n\t});\n\tregisterProxy(proxy, ep);\n\treturn proxy as any;\n}\n\nfunction myFlat<T>(arr: (T | T[])[]): T[] {\n\treturn Array.prototype.concat.apply([], arr);\n}\n\nfunction processArguments(argumentList: any[]): [WireValue[], Transferable[]] {\n\tconst processed = argumentList.map(toWireValue);\n\treturn [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\n\nconst transferCache = new WeakMap<any, Transferable[]>();\nexport function transfer<T>(obj: T, transfers: Transferable[]): T {\n\ttransferCache.set(obj, transfers);\n\treturn obj;\n}\n\nexport function proxy<T extends object>(obj: T): T & ProxyMarked {\n\treturn Object.assign(obj, { [proxyMarker]: true }) as any;\n}\n\nexport function windowEndpoint(\n\tw: PostMessageWithOrigin,\n\tcontext: EventSource = globalThis,\n\ttargetOrigin = '*'\n): Endpoint {\n\treturn {\n\t\tpostMessage: (msg: any, transferables: Transferable[]) =>\n\t\t\tw.postMessage(msg, targetOrigin, transferables),\n\t\taddEventListener: context.addEventListener.bind(context),\n\t\tremoveEventListener: context.removeEventListener.bind(context),\n\t};\n}\n\nfunction toWireValue(value: any): [WireValue, Transferable[]] {\n\tfor (const [name, handler] of transferHandlers) {\n\t\tif (handler.canHandle(value)) {\n\t\t\tconst [serializedValue, transferables] = handler.serialize(value);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: WireValueType.HANDLER,\n\t\t\t\t\tname,\n\t\t\t\t\tvalue: serializedValue,\n\t\t\t\t},\n\t\t\t\ttransferables,\n\t\t\t];\n\t\t}\n\t}\n\treturn [\n\t\t{\n\t\t\ttype: WireValueType.RAW,\n\t\t\tvalue,\n\t\t},\n\t\ttransferCache.get(value) || [],\n\t];\n}\n\nfunction fromWireValue(value: WireValue): any {\n\tswitch (value.type) {\n\t\tcase WireValueType.HANDLER:\n\t\t\treturn transferHandlers.get(value.name)!.deserialize(value.value);\n\t\tcase WireValueType.RAW:\n\t\t\treturn value.value;\n\t}\n}\n\nfunction requestResponseMessage(\n\tep: Endpoint,\n\tpendingListeners: PendingListenersMap,\n\tmsg: Message,\n\ttransfers?: Transferable[]\n): Promise<WireValue> {\n\treturn new Promise((resolve) => {\n\t\tconst id = generateUUID();\n\t\tpendingListeners.set(id, resolve);\n\t\tif (ep.start) {\n\t\t\tep.start();\n\t\t}\n\t\tep.postMessage({ id, ...msg }, transfers);\n\t});\n}\n\nfunction generateUUID(): string {\n\treturn new Array(4)\n\t\t.fill(0)\n\t\t.map(() =>\n\t\t\tMath.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)\n\t\t)\n\t\t.join('-');\n}\n\n// node-adapter.ts:\n\nexport interface NodeEndpoint {\n\tpostMessage(message: any, transfer?: any[]): void;\n\ton(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n\toff(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n\tstart?: () => void;\n}\n\nexport function nodeEndpoint(nep: NodeEndpoint): Endpoint {\n\tconst listeners = new WeakMap();\n\treturn {\n\t\tpostMessage: nep.postMessage.bind(nep),\n\t\taddEventListener: (_, eh) => {\n\t\t\tconst l = (data: any) => {\n\t\t\t\tif ('handleEvent' in eh) {\n\t\t\t\t\teh.handleEvent({ data } as MessageEvent);\n\t\t\t\t} else {\n\t\t\t\t\teh({ data } as MessageEvent);\n\t\t\t\t}\n\t\t\t};\n\t\t\tnep.on('message', l);\n\t\t\tlisteners.set(eh, l);\n\t\t},\n\t\tremoveEventListener: (_, eh) => {\n\t\t\tconst l = listeners.get(eh);\n\t\t\tif (!l) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnep.off('message', l);\n\t\t\tlisteners.delete(eh);\n\t\t},\n\t\tstart: nep.start && nep.start.bind(nep),\n\t};\n}\n","/**\n * `serialize-error` package wrapped as a single file for compatibility\n * with both CJS and ESM.\n *\n * @see https://github.com/sindresorhus/serialize-error\n */\nconst list = [\n\t// Native ES errors https://262.ecma-international.org/12.0/#sec-well-known-intrinsic-objects\n\tError,\n\tEvalError,\n\tRangeError,\n\tReferenceError,\n\tSyntaxError,\n\tTypeError,\n\tURIError,\n\tAggregateError,\n\n\t// Built-in errors\n\tglobalThis.DOMException,\n\n\t// Node-specific errors\n\t// https://nodejs.org/api/errors.html\n\t(globalThis as any).AssertionError,\n\t(globalThis as any).SystemError,\n]\n\t// Non-native Errors are used with `globalThis` because they might be missing. This filter drops\n\t// them when undefined.\n\t.filter(Boolean)\n\t.map((constructor) => [constructor.name, constructor]);\n\nexport type ErrorObject = {\n\tname?: string;\n\tmessage?: string;\n\tstack?: string;\n\tcause?: unknown;\n\tcode?: string;\n} & Record<string, unknown>;\n\nexport const errorConstructors = new Map(list as any);\n\nexport function addKnownErrorConstructor(constructor: any) {\n\tconst { name } = constructor;\n\tif (errorConstructors.has(name)) {\n\t\tthrow new Error(`The error constructor \"${name}\" is already known.`);\n\t}\n\n\ttry {\n\t\t// eslint-disable-next-line no-new -- It just needs to be verified\n\t\tnew constructor();\n\t} catch (error) {\n\t\tthrow new Error(`The error constructor \"${name}\" is not compatible`, {\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\terrorConstructors.set(name, constructor);\n}\n\nexport class NonError extends Error {\n\toverride name = 'NonError';\n\n\tconstructor(message: any) {\n\t\tsuper(NonError._prepareSuperMessage(message));\n\t}\n\n\tstatic _prepareSuperMessage(message: any) {\n\t\ttry {\n\t\t\treturn JSON.stringify(message);\n\t\t} catch {\n\t\t\treturn String(message);\n\t\t}\n\t}\n}\n\nconst errorProperties = [\n\t{\n\t\tproperty: 'name',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'message',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'stack',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'code',\n\t\tenumerable: true,\n\t},\n\t{\n\t\tproperty: 'cause',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'errors',\n\t\tenumerable: false,\n\t},\n];\n\nconst toJsonWasCalled = new WeakSet();\n\nconst toJSON = (from: any) => {\n\ttoJsonWasCalled.add(from);\n\tconst json = from.toJSON();\n\ttoJsonWasCalled.delete(from);\n\treturn json;\n};\n\nconst newError = (name: any) => {\n\tconst ErrorConstructor = errorConstructors.get(name) ?? (Error as any);\n\treturn ErrorConstructor === AggregateError\n\t\t? new ErrorConstructor([])\n\t\t: new ErrorConstructor();\n};\n\n// eslint-disable-next-line complexity\nconst destroyCircular = ({\n\tfrom,\n\tseen,\n\tto,\n\tforceEnumerable,\n\tmaxDepth,\n\tdepth,\n\tuseToJSON,\n\tserialize,\n}: {\n\tfrom?: any;\n\tseen: any[];\n\tto?: any;\n\tforceEnumerable: boolean;\n\tmaxDepth: number;\n\tdepth: number;\n\tuseToJSON: boolean;\n\tserialize: boolean;\n}) => {\n\tif (!to) {\n\t\tif (Array.isArray(from)) {\n\t\t\tto = [];\n\t\t} else if (!serialize && isErrorLike(from)) {\n\t\t\tto = newError(from.name);\n\t\t} else {\n\t\t\tto = {};\n\t\t}\n\t}\n\n\tseen.push(from);\n\n\tif (depth >= maxDepth) {\n\t\treturn to;\n\t}\n\n\tif (\n\t\tuseToJSON &&\n\t\ttypeof from.toJSON === 'function' &&\n\t\t!toJsonWasCalled.has(from)\n\t) {\n\t\treturn toJSON(from);\n\t}\n\n\tconst continueDestroyCircular = (value: any) =>\n\t\tdestroyCircular({\n\t\t\tfrom: value,\n\t\t\tseen: [...seen],\n\t\t\tforceEnumerable,\n\t\t\tmaxDepth,\n\t\t\tdepth,\n\t\t\tuseToJSON,\n\t\t\tserialize,\n\t\t});\n\n\tfor (const [key, value] of Object.entries(from)) {\n\t\tif (\n\t\t\tvalue &&\n\t\t\tvalue instanceof Uint8Array &&\n\t\t\tvalue.constructor.name === 'Buffer'\n\t\t) {\n\t\t\tto[key] = '[object Buffer]';\n\t\t\tcontinue;\n\t\t}\n\n\t\t// TODO: Use `stream.isReadable()` when targeting Node.js 18.\n\t\tif (\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof (value as any).pipe === 'function'\n\t\t) {\n\t\t\tto[key] = '[object Stream]';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (typeof value === 'function') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!value || typeof value !== 'object') {\n\t\t\t// Gracefully handle non-configurable errors like `DOMException`.\n\t\t\ttry {\n\t\t\t\tto[key] = value;\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!seen.includes(from[key])) {\n\t\t\tdepth++;\n\t\t\tto[key] = continueDestroyCircular(from[key]);\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tto[key] = '[Circular]';\n\t}\n\n\tif (serialize || to instanceof Error) {\n\t\tfor (const { property, enumerable } of errorProperties) {\n\t\t\tif (from[property] !== undefined && from[property] !== null) {\n\t\t\t\tObject.defineProperty(to, property, {\n\t\t\t\t\tvalue:\n\t\t\t\t\t\tisErrorLike(from[property]) ||\n\t\t\t\t\t\tArray.isArray(from[property])\n\t\t\t\t\t\t\t? continueDestroyCircular(from[property])\n\t\t\t\t\t\t\t: from[property],\n\t\t\t\t\tenumerable: forceEnumerable ? true : enumerable,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\nexport function serializeError(value: any, options: any = {}) {\n\tconst { maxDepth = Number.POSITIVE_INFINITY, useToJSON = true } = options;\n\n\tif (typeof value === 'object' && value !== null) {\n\t\treturn destroyCircular({\n\t\t\tfrom: value,\n\t\t\tseen: [],\n\t\t\tforceEnumerable: true,\n\t\t\tmaxDepth,\n\t\t\tdepth: 0,\n\t\t\tuseToJSON,\n\t\t\tserialize: true,\n\t\t});\n\t}\n\n\t// People sometimes throw things besides Error objects…\n\tif (typeof value === 'function') {\n\t\t// `JSON.stringify()` discards functions. We do too, unless a function is thrown directly.\n\t\t// We intentionally use `||` because `.name` is an empty string for anonymous functions.\n\t\treturn `[Function: ${value.name || 'anonymous'}]`;\n\t}\n\n\treturn value;\n}\n\nexport function deserializeError(value: any, options: any = {}) {\n\tconst { maxDepth = Number.POSITIVE_INFINITY } = options;\n\n\tif (value instanceof Error) {\n\t\treturn value;\n\t}\n\n\tif (isMinimumViableSerializedError(value)) {\n\t\treturn destroyCircular({\n\t\t\tfrom: value,\n\t\t\tseen: [],\n\t\t\tto: newError(value.name),\n\t\t\tmaxDepth,\n\t\t\tdepth: 0,\n\t\t\tserialize: false,\n\t\t} as any);\n\t}\n\n\treturn new NonError(value);\n}\n\nexport function isErrorLike(value: any) {\n\treturn (\n\t\tBoolean(value) &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.name === 'string' &&\n\t\ttypeof value.message === 'string' &&\n\t\ttypeof value.stack === 'string'\n\t);\n}\n\n// Used as a weak check for immediately-passed objects, whereas `isErrorLike` is used for nested\n// values to avoid bad detection\nfunction isMinimumViableSerializedError(value: any) {\n\t// @ts-ignore\n\treturn (\n\t\tBoolean(value) &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.message === 'string' &&\n\t\t!Array.isArray(value)\n\t);\n}\n","import type { PHPResponseData } from './php-response';\nimport { PHPResponse, StreamedPHPResponse } from './php-response';\nimport * as Comlink from './comlink-sync';\nimport {\n\tNodeSABSyncReceiveMessageTransport,\n\tnodeEndpoint,\n\ttype NodeEndpoint,\n\ttype Remote,\n\ttype Endpoint,\n\ttype IsomorphicMessagePort,\n} from './comlink-sync';\nimport * as ErrorSerializer from './serialize-error';\n\nexport type WithAPIState = {\n\t/**\n\t * Resolves to true when the remote API is ready for\n\t * Comlink communication, but not necessarily fully initialized yet.\n\t */\n\tisConnected: () => Promise<void>;\n\t/**\n\t * Resolves to true when the remote API is declares it's\n\t * fully loaded and ready to be used.\n\t */\n\tisReady: () => Promise<void>;\n};\nexport type RemoteAPI<T> = Remote<T> & WithAPIState;\n\nexport async function consumeAPISync<APIType>(\n\tremote: IsomorphicMessagePort\n): Promise<APIType> {\n\tsetupTransferHandlers();\n\tconst transport = await NodeSABSyncReceiveMessageTransport.create();\n\treturn Comlink.wrapSync<APIType>(remote, transport);\n}\n\nexport function consumeAPI<APIType>(\n\tremote: Worker | Window | NodeEndpoint,\n\tcontext: undefined | EventTarget = undefined\n): RemoteAPI<APIType> {\n\tsetupTransferHandlers();\n\n\tlet endpoint;\n\tconst appearsToBeNodeEnvironment = import.meta.url.startsWith('file://');\n\tif (appearsToBeNodeEnvironment) {\n\t\tendpoint = nodeEndpoint(remote as NodeEndpoint);\n\t} else {\n\t\tendpoint =\n\t\t\tremote instanceof Worker\n\t\t\t\t? remote\n\t\t\t\t: Comlink.windowEndpoint(remote as Window, context);\n\t}\n\n\t/**\n\t * This shouldn't be necessary, but Comlink doesn't seem to\n\t * handle the initial isConnected() call correctly unless it's\n\t * explicitly provided here. This is especially weird\n\t * since the only thing this proxy does is to call the\n\t * isConnected() method on the remote API.\n\t *\n\t * @TODO: Remove this workaround.\n\t */\n\tconst api = Comlink.wrap<APIType & WithAPIState>(endpoint);\n\tconst methods = proxyClone(api);\n\treturn new Proxy(methods, {\n\t\tget: (target, prop) => {\n\t\t\tif (prop === 'isConnected') {\n\t\t\t\treturn async () => {\n\t\t\t\t\t// Keep retrying until the remote API confirms it's connected.\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait runWithTimeout(api.isConnected(), 200);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Timeout exceeded, try again. We can't just use a single\n\t\t\t\t\t\t\t// `runWithTimeout` call because it won't reach the remote API\n\t\t\t\t\t\t\t// if it's not connected yet. Instead, we need to keep retrying\n\t\t\t\t\t\t\t// until the remote API is connected and registers a handler\n\t\t\t\t\t\t\t// for the `isConnected` method.\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\treturn (api as any)[prop];\n\t\t},\n\t}) as unknown as RemoteAPI<APIType>;\n}\n\nasync function runWithTimeout<T>(\n\tpromise: Promise<T>,\n\ttimeout: number\n): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tsetTimeout(reject, timeout);\n\t\tpromise.then(resolve);\n\t});\n}\n\nexport type PublicAPI<Methods, PipedAPI = unknown> = RemoteAPI<\n\tMethods & PipedAPI\n>;\n\nexport function exposeAPI<Methods, PipedAPI>(\n\tapiMethods?: Methods,\n\tpipedApi?: PipedAPI,\n\ttargetWorker?: NodeEndpoint\n): [() => void, (e: Error) => void, PublicAPI<Methods, PipedAPI>] {\n\tconst { setReady, setFailed, exposedApi } = prepareForExpose(\n\t\tapiMethods,\n\t\tpipedApi\n\t);\n\tlet endpoint: Endpoint | undefined;\n\tif (targetWorker) {\n\t\t// NOTE: If there are other target types, we could expand this later,\n\t\t// but for now, we only need support for NodeEndpoints.\n\t\tendpoint = nodeEndpoint(targetWorker);\n\t} else {\n\t\tendpoint =\n\t\t\ttypeof window !== 'undefined'\n\t\t\t\t? Comlink.windowEndpoint(self.parent)\n\t\t\t\t: undefined;\n\t}\n\tComlink.expose(exposedApi, endpoint);\n\treturn [setReady, setFailed, exposedApi as PublicAPI<Methods, PipedAPI>];\n}\n\nexport async function exposeSyncAPI<Methods>(\n\tapiMethods: Methods,\n\tport: IsomorphicMessagePort\n): Promise<[() => void, (e: Error) => void, Methods]> {\n\tconst { setReady, setFailed, exposedApi } = prepareForExpose(apiMethods);\n\tconst transport = await NodeSABSyncReceiveMessageTransport.create();\n\tconst endpoint = nodeEndpoint(port as any);\n\tComlink.exposeSync(exposedApi, endpoint, transport);\n\treturn [setReady, setFailed, exposedApi as Methods];\n}\n\nfunction prepareForExpose<Methods, PipedAPI>(\n\tapiMethods?: Methods,\n\tpipedApi?: PipedAPI\n) {\n\tsetupTransferHandlers();\n\n\tconst connected = Promise.resolve();\n\n\tlet setReady: any;\n\tlet setFailed: any;\n\tconst ready = new Promise((resolve, reject) => {\n\t\tsetReady = resolve;\n\t\tsetFailed = reject;\n\t});\n\n\tconst methods = proxyClone(apiMethods);\n\tconst exposedApi = new Proxy(methods, {\n\t\tget: (target, prop) => {\n\t\t\tif (prop === 'isConnected') {\n\t\t\t\treturn () => connected;\n\t\t\t} else if (prop === 'isReady') {\n\t\t\t\treturn () => ready;\n\t\t\t} else if (prop in target) {\n\t\t\t\treturn target[prop];\n\t\t\t}\n\t\t\treturn (pipedApi as any)?.[prop];\n\t\t},\n\t}) as unknown as PublicAPI<Methods, PipedAPI>;\n\n\treturn { setReady, setFailed, exposedApi };\n}\n\nlet isTransferHandlersSetup = false;\nfunction setupTransferHandlers() {\n\tif (isTransferHandlersSetup) {\n\t\treturn;\n\t}\n\tisTransferHandlersSetup = true;\n\tComlink.transferHandlers.set('EVENT', {\n\t\tcanHandle: (obj): obj is CustomEvent => obj instanceof CustomEvent,\n\t\tserialize: (ev: CustomEvent) => {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tdetail: ev.detail,\n\t\t\t\t},\n\t\t\t\t[],\n\t\t\t];\n\t\t},\n\t\tdeserialize: (obj) => obj,\n\t});\n\tComlink.transferHandlers.set('FUNCTION', {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n\t\tcanHandle: (obj: unknown): obj is Function => typeof obj === 'function',\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n\t\tserialize(obj: Function) {\n\t\t\tconst { port1, port2 } = new MessageChannel();\n\t\t\tComlink.expose(obj, port1);\n\t\t\treturn [port2, [port2]];\n\t\t},\n\t\tdeserialize(port: any) {\n\t\t\tport.start();\n\t\t\treturn Comlink.wrap(port);\n\t\t},\n\t});\n\tComlink.transferHandlers.set('MESSAGE_PORT', {\n\t\tcanHandle: (obj: unknown): obj is MessagePort =>\n\t\t\tobj instanceof MessagePort,\n\t\tserialize(port: MessagePort): [MessagePort, Transferable[]] {\n\t\t\treturn [port, [port]];\n\t\t},\n\t\tdeserialize(port: MessagePort): MessagePort {\n\t\t\treturn port;\n\t\t},\n\t});\n\tComlink.transferHandlers.set('PHPResponse', {\n\t\tcanHandle: (obj: unknown): obj is PHPResponseData =>\n\t\t\ttypeof obj === 'object' &&\n\t\t\tobj !== null &&\n\t\t\t'headers' in obj &&\n\t\t\t'bytes' in obj &&\n\t\t\t'errors' in obj &&\n\t\t\t'exitCode' in obj &&\n\t\t\t'httpStatusCode' in obj,\n\t\tserialize(obj: PHPResponse): [PHPResponseData, Transferable[]] {\n\t\t\treturn [obj.toRawData(), []];\n\t\t},\n\t\tdeserialize(responseData: PHPResponseData): PHPResponse {\n\t\t\treturn PHPResponse.fromRawData(responseData);\n\t\t},\n\t});\n\t// Augment Comlink's throw handler to include Error the response and source\n\t// information in the serialized error object. BasePHP may throw\n\t// PHPExecutionFailureError which includes those information and we'll want to\n\t// display them for the user.\n\tconst throwHandler = Comlink.transferHandlers.get('throw')!;\n\tconst originalSerialize = throwHandler?.serialize;\n\tthrowHandler.serialize = ({ value }: any) => {\n\t\tconst serialized = originalSerialize({ value }) as any;\n\t\tif (value.response) {\n\t\t\tserialized[0].value.response = value.response;\n\t\t}\n\t\tif (value.source) {\n\t\t\tserialized[0].value.source = value.source;\n\t\t}\n\t\treturn serialized;\n\t};\n\n\tComlink.transferHandlers.set('StreamedPHPResponse', {\n\t\tcanHandle: (obj: unknown): obj is StreamedPHPResponse =>\n\t\t\tobj instanceof StreamedPHPResponse,\n\t\tserialize(obj: StreamedPHPResponse): [any, Transferable[]] {\n\t\t\tconst supportsStreams = supportsTransferableStreams();\n\t\t\tconst exitCodePort = promiseToPort(obj.exitCode);\n\t\t\tif (supportsStreams) {\n\t\t\t\tconst payload = {\n\t\t\t\t\t__type: 'StreamedPHPResponse',\n\t\t\t\t\theaders: (obj as any)['headersStream'],\n\t\t\t\t\tstdout: obj.stdout,\n\t\t\t\t\tstderr: obj.stderr,\n\t\t\t\t\texitCodePort,\n\t\t\t\t};\n\t\t\t\treturn [payload, [exitCodePort]];\n\t\t\t}\n\t\t\t// Fallback: bridge streams via MessagePorts\n\t\t\tconst headersPort = streamToPort((obj as any)['headersStream']);\n\t\t\tconst stdoutPort = streamToPort(obj.stdout);\n\t\t\tconst stderrPort = streamToPort(obj.stderr);\n\t\t\tconst payload = {\n\t\t\t\t__type: 'StreamedPHPResponse',\n\t\t\t\theadersPort,\n\t\t\t\tstdoutPort,\n\t\t\t\tstderrPort,\n\t\t\t\texitCodePort,\n\t\t\t};\n\t\t\treturn [\n\t\t\t\tpayload,\n\t\t\t\t[headersPort, stdoutPort, stderrPort, exitCodePort],\n\t\t\t];\n\t\t},\n\t\tdeserialize(data: any): StreamedPHPResponse {\n\t\t\tif (data.headers && data.stdout && data.stderr) {\n\t\t\t\tconst exitCode = portToPromise(\n\t\t\t\t\tdata.exitCodePort as MessagePort\n\t\t\t\t);\n\t\t\t\treturn new StreamedPHPResponse(\n\t\t\t\t\tdata.headers as ReadableStream<Uint8Array>,\n\t\t\t\t\tdata.stdout as ReadableStream<Uint8Array>,\n\t\t\t\t\tdata.stderr as ReadableStream<Uint8Array>,\n\t\t\t\t\texitCode\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst headers = portToStream(data.headersPort as MessagePort);\n\t\t\tconst stdout = portToStream(data.stdoutPort as MessagePort);\n\t\t\tconst stderr = portToStream(data.stderrPort as MessagePort);\n\t\t\tconst exitCode = portToPromise(data.exitCodePort as MessagePort);\n\t\t\treturn new StreamedPHPResponse(headers, stdout, stderr, exitCode);\n\t\t},\n\t});\n}\n\n// Utilities for transferring ReadableStreams and Promises via MessagePorts:\n\n/**\n * Safari does not support transferable streams, so we need to fallback to\n * MessagePorts.\n * Feature-detects whether this runtime supports transferring ReadableStreams\n * directly through postMessage (aka \"transferable streams\"). When false,\n * we must fall back to port-bridged streaming.\n */\nfunction supportsTransferableStreams(): boolean {\n\ttry {\n\t\tif (typeof ReadableStream === 'undefined') return false;\n\t\tconst { port1 } = new MessageChannel();\n\t\tconst rs = new ReadableStream();\n\t\tport1.postMessage(rs as any);\n\t\ttry {\n\t\t\tport1.close();\n\t\t} catch (_e) {\n\t\t\tvoid _e;\n\t\t}\n\t\treturn true;\n\t} catch (_e) {\n\t\tvoid _e;\n\t\treturn false;\n\t}\n}\n\n/**\n * Bridges a ReadableStream to a MessagePort by reading chunks and posting\n * messages to the port. Used as a fallback when transferable streams are not\n * supported (e.g., Safari).\n *\n * Protocol of the returned MessagePort:\n *\n * { t: 'chunk', b: ArrayBuffer } – next binary chunk\n * { t: 'close' } – end of stream\n * { t: 'error', m: string } – terminal error\n */\nfunction streamToPort(stream: ReadableStream<Uint8Array>): MessagePort {\n\tconst { port1, port2 } = new MessageChannel();\n\t(async () => {\n\t\tconst reader = stream.getReader();\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tport1.postMessage({ t: 'close' });\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Ignore error\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tport1.close();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Ignore error\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (value) {\n\t\t\t\t\t// Ensure we transfer an owned buffer\n\t\t\t\t\tconst owned =\n\t\t\t\t\t\tvalue.byteOffset === 0 &&\n\t\t\t\t\t\tvalue.byteLength === value.buffer.byteLength\n\t\t\t\t\t\t\t? value\n\t\t\t\t\t\t\t: value.slice();\n\t\t\t\t\tconst buf = owned.buffer;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tport1.postMessage({ t: 'chunk', b: buf }, [\n\t\t\t\t\t\t\tbuf as unknown as Transferable,\n\t\t\t\t\t\t]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tport1.postMessage({\n\t\t\t\t\t\t\tt: 'chunk',\n\t\t\t\t\t\t\tb: owned.buffer.slice(0),\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} catch (e: any) {\n\t\t\ttry {\n\t\t\t\tport1.postMessage({ t: 'error', m: e?.message || String(e) });\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tport1.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t}\n\t})();\n\treturn port2;\n}\n\n/**\n * Reconstructs a ReadableStream from a MessagePort using the inverse of the\n * streamToPort protocol. Each message enqueues data, closes, or errors.\n */\nfunction portToStream(port: MessagePort): ReadableStream<Uint8Array> {\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tconst onMessage = (ev: MessageEvent) => {\n\t\t\t\tconst data: any = (ev as any).data;\n\t\t\t\tif (!data) return;\n\t\t\t\tswitch (data.t) {\n\t\t\t\t\tcase 'chunk':\n\t\t\t\t\t\tcontroller.enqueue(new Uint8Array(data.b));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'close':\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'error':\n\t\t\t\t\t\tcontroller.error(new Error(data.m || 'Stream error'));\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst cleanup = () => {\n\t\t\t\ttry {\n\t\t\t\t\tport.removeEventListener?.('message', onMessage as any);\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tport.onmessage = null;\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tport.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (port.addEventListener) {\n\t\t\t\tport.addEventListener('message', onMessage as any);\n\t\t\t} else if ((port as any).on) {\n\t\t\t\t(port as any).on('message', (data: any) =>\n\t\t\t\t\tonMessage({ data } as any)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tport.onmessage = onMessage as any;\n\t\t\t}\n\t\t\tif (typeof port.start === 'function') {\n\t\t\t\tport.start();\n\t\t\t}\n\t\t},\n\t\tcancel() {\n\t\t\ttry {\n\t\t\t\tport.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Bridges a Promise to a MessagePort so it can be delivered across threads.\n *\n * Protocol of the returned MessagePort:\n *\n * { t: 'resolve', v: any } – promise resolved with value v\n * { t: 'reject', m: str } – promise rejected with message m\n */\nfunction promiseToPort(promise: Promise<any>): MessagePort {\n\tconst { port1, port2 } = new MessageChannel();\n\tpromise\n\t\t.then((value) => {\n\t\t\ttry {\n\t\t\t\tport1.postMessage({ t: 'resolve', v: value });\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t})\n\t\t.catch((err) => {\n\t\t\ttry {\n\t\t\t\tport1.postMessage({\n\t\t\t\t\tt: 'reject',\n\t\t\t\t\tm: (err as any)?.message || String(err),\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t})\n\t\t.finally(() => {\n\t\t\ttry {\n\t\t\t\tport1.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t});\n\treturn port2;\n}\n\n/**\n * Reconstructs a Promise from a MessagePort using the inverse of\n * promiseToPort. Resolves or rejects when the corresponding message arrives.\n */\nfunction portToPromise(port: MessagePort): Promise<any> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst onMessage = (ev: MessageEvent) => {\n\t\t\tconst data: any = (ev as any).data;\n\t\t\tif (!data) return;\n\t\t\tif (data.t === 'resolve') {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(data.v);\n\t\t\t} else if (data.t === 'reject') {\n\t\t\t\tcleanup();\n\t\t\t\treject(new Error(data.m || ''));\n\t\t\t}\n\t\t};\n\t\tconst cleanup = () => {\n\t\t\ttry {\n\t\t\t\tport.removeEventListener?.('message', onMessage as any);\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tport.onmessage = null;\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tport.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t};\n\t\tif (port.addEventListener) {\n\t\t\tport.addEventListener('message', onMessage as any);\n\t\t} else if ((port as any).on) {\n\t\t\t(port as any).on('message', (data: any) =>\n\t\t\t\tonMessage({ data } as any)\n\t\t\t);\n\t\t} else {\n\t\t\tport.onmessage = onMessage as any;\n\t\t}\n\t\tif (typeof port.start === 'function') {\n\t\t\tport.start();\n\t\t}\n\t});\n}\n\n// Augment Comlink's throw handler to include all the information carried by\n// the thrown object, including the cause, additional properties, etc.\ninterface UnserializedError {\n\tvalue: unknown;\n}\ntype SerializedError =\n\t| { isError: true; value: ErrorSerializer.ErrorObject }\n\t| { isError: false; value: unknown };\n\nconst throwTransferHandler = Comlink.transferHandlers.get(\n\t'throw'\n) as Comlink.TransferHandler<UnserializedError, SerializedError>;\n\nconst throwTransferHandlerCustom: Comlink.TransferHandler<\n\tUnserializedError,\n\tSerializedError\n> = {\n\tcanHandle: throwTransferHandler.canHandle,\n\tserialize: ({ value }) => {\n\t\tlet serialized: SerializedError;\n\t\tif (value instanceof Error) {\n\t\t\tserialized = {\n\t\t\t\tisError: true,\n\t\t\t\tvalue: ErrorSerializer.serializeError(value),\n\t\t\t};\n\t\t\t// The error class name is not serialized by serialize-error, let's add it manually.\n\t\t\tserialized.value['originalErrorClassName'] = value.constructor.name;\n\t\t} else {\n\t\t\tserialized = { isError: false, value };\n\t\t}\n\t\treturn [serialized, []];\n\t},\n\tdeserialize: (serialized) => {\n\t\tif (serialized.isError) {\n\t\t\tconst error = ErrorSerializer.deserializeError(serialized.value);\n\t\t\t/**\n\t\t\t * The original error from the web worker does not include any call\n\t\t\t * stack from the Playground web app. Let's include that information\n\t\t\t * in the error chain.\n\t\t\t *\n\t\t\t * We'll place it at the bottom of the error chain. This way the API\n\t\t\t * consumer gets the original error object and not an opaque\n\t\t\t * \"Comlink method call failed\" error, but they can still inspect\n\t\t\t * it further to see the full call stack.\n\t\t\t */\n\t\t\tconst additionalCallStack = new Error('Comlink method call failed');\n\t\t\tlet deepestError = error;\n\t\t\twhile (deepestError.cause) {\n\t\t\t\tdeepestError = deepestError.cause;\n\t\t\t}\n\t\t\tdeepestError.cause = additionalCallStack;\n\t\t\tthrow error;\n\t\t}\n\t\tthrow serialized.value;\n\t},\n};\n\nComlink.transferHandlers.set('throw', throwTransferHandlerCustom);\n\nfunction proxyClone(object: any): any {\n\treturn new Proxy(object, {\n\t\tget(target, prop) {\n\t\t\tswitch (typeof target[prop]) {\n\t\t\t\tcase 'function':\n\t\t\t\t\treturn (...args: any[]) => target[prop](...args);\n\t\t\t\tcase 'object':\n\t\t\t\t\tif (target[prop] === null) {\n\t\t\t\t\t\treturn target[prop];\n\t\t\t\t\t}\n\t\t\t\t\treturn proxyClone(target[prop]);\n\t\t\t\tcase 'undefined':\n\t\t\t\tcase 'number':\n\t\t\t\tcase 'string':\n\t\t\t\t\treturn target[prop];\n\t\t\t\tdefault:\n\t\t\t\t\treturn Comlink.proxy(target[prop]);\n\t\t\t}\n\t\t},\n\t});\n}\n"],"names":["errno","message","options","e","messagePrefix","value","args","errmsg","path","formattedPrefix","FS","data","fromPath","toPath","fromMount","toMount","dirname","mountPoint","file","filePath","joinPaths","files","name","prepend","logger","target","link","fromNode","filenames","filename","requestHandler","monitor","__privateAdd","_eventListeners","__privateSet","php","internalUrl","callback","_a","request","reap","argv","response","error","newName","listener","l","key","eventType","__privateGet","event","listeners","returnData","phpLoaderModule","phpModuleArgs","phpReady","resolvePHP","rejectPHP","PHPRuntime","reason","id","code","methods","promise","resolve","reject","headers","stdout","stderr","exitCode","statusCode","result","bytes","headersStream","headersText","headersData","line","colonIndex","headerName","headerValue","stream","reader","text","done","chunks","totalLength","acc","chunk","offset","httpStatusCode","body","errors","streamedResponse","type","runtime","original","clearMessage","crypticError","asyncifyStack","betterMessage","uniqueFunctions","lastError","fn","stack","names","parts","isWasm","source","PHPRuntimeId","_PHP_instances","_sapiName","_phpWasmInitCalled","_wasmErrorsTarget","_messageListeners","_mounts","_rotationOptions","Semaphore","createSpawnHandler","runtimeId","opcacheConfig","mode","syncResponse","release","heapBodyPointer","streamedResponsePromise","__privateMethod","executeWithErrorHandling_fn","setRelativeRequestUri_fn","setRequestMethod_fn","requestHeaders","host","port","inferPortFromHostAndProtocol_fn","setRequestHost_fn","setRequestPort_fn","setRequestHeaders_fn","setRequestBody_fn","setScriptPath_fn","$_SERVER","prepareServerEntries_fn","setServerGlobalEntry_fn","env","setEnv_fn","cleanup","consts","oldFS","oldRootLevelPaths","oldSpawnProcess","oldCWD","mountHandlersToReapplyInOrder","vfsPath","mount","mountsToUnmountInReverseOrder","newFs","mountHandler","virtualFSPath","unmountCallback","mountObject","basename","arg","process","stderrStream","stdoutStream","controller","shouldSkip","defaults","HTTP_prefix","uri","queryString","protocol","method","size","contentLength","executionFn","emscriptenModule","streamsClosed","headersClosed","closeHeadersStream","errorListener","exitCodePromise","_","normalized","oldNode","controllerResolve","controllerPromise","fs","entries","ini","parse","stringify","phpIniValues","iniBefore","current","isFirst","hasHeaders","setCookie","equalsIndex","cookiesArray","buffer","root","relativePaths","pathPrefix","exceptPaths","normalizePath","currentParent","absPath","StreamedFile","limit","considerPrimary","spawnedPhp","factoryArgs","spawned","pop","instance","rejection","AcquireTimeoutError","url","prefix","boundary","contentType","textEncoder","length","part","fileBuffer","config","_PHPRequestHandler_instances","_DOCROOT","_PROTOCOL","_HOSTNAME","_PORT","_HOST","_PATHNAME","_ABSOLUTE_URL","_cookieStore","documentRoot","absoluteUrl","rewriteRules","getFileNotFoundAction","info","isNonStandardPort","isAbsolute","originalRequestUrl","rewrittenRequestUrl","applyRewriteRules_fn","primaryPhp","fsPath","possibleIndexFile","possibleIndexPath","pathToTry","resolvedPathToTry","fileNotFoundAction","spawnPHPAndDispatchRequest_fn","serveStaticFile_fn","resolvedScriptPath","siteRelativePath","rewrittenRequestPath","arrayBuffer","scriptPath","spawnedPHP","dispatchToPHP_fn","preferredMethod","executionError","extension","rules","rule","recreateRuntime","maxRequests","newFiles","rmRoot","relativePath","content","sourceOfTruth","replica","paths","__private__symbol","fsResult","processManager","processApi","binaryName","cwd","obj","ep","transport","allowedOrigins","_t","prop","res","v","xfer","_thisArg","rawArgs","argList","wire","m","ev","notifyBuffer","view","msg","transferables","latch","val","port1","port2","throwTransferHandler","serialized","origin","allowedOrigin","afterResponseSent","argumentList","returnValue","parent","rawValue","wireValue","endpoint","pendingListeners","resolver","isReleased","newCount","proxy","isProxyReleased","_target","r","p","rawArgumentList","last","arr","processed","transfers","w","context","targetOrigin","handler","serializedValue","nep","eh","constructor","from","json","ErrorConstructor","seen","to","forceEnumerable","maxDepth","depth","useToJSON","serialize","continueDestroyCircular","property","enumerable","remote","Comlink.wrapSync","Comlink.windowEndpoint","api","Comlink.wrap","timeout","apiMethods","pipedApi","targetWorker","setReady","setFailed","exposedApi","Comlink.expose","Comlink.exposeSync","connected","ready","Comlink.transferHandlers","responseData","throwHandler","originalSerialize","supportsStreams","exitCodePort","headersPort","stdoutPort","stderrPort","rs","owned","buf","onMessage","err","ErrorSerializer.serializeError","ErrorSerializer.deserializeError","additionalCallStack","deepestError","object","Comlink.proxy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/universal/src/lib/rethrow-file-system-error.ts","../../../../packages/php-wasm/universal/src/lib/fs-helpers.ts","../../../../packages/php-wasm/universal/src/lib/php-worker.ts","../../../../packages/php-wasm/universal/src/lib/is-exit-code.ts","../../../../packages/php-wasm/universal/src/lib/load-php-runtime.ts","../../../../packages/php-wasm/universal/src/lib/php-response.ts","../../../../packages/php-wasm/universal/src/lib/error-event-polyfill.ts","../../../../packages/php-wasm/universal/src/lib/wasm-error-reporting.ts","../../../../packages/php-wasm/universal/src/lib/php.ts","../../../../packages/php-wasm/universal/src/lib/ini.ts","../../../../packages/php-wasm/universal/src/lib/error-reporting.ts","../../../../packages/php-wasm/universal/src/lib/http-cookie-store.ts","../../../../packages/php-wasm/universal/src/lib/stream-read-file-from-php.ts","../../../../packages/php-wasm/universal/src/lib/iterate-files.ts","../../../../packages/php-wasm/universal/src/lib/write-files-stream-to-php.ts","../../../../packages/php-wasm/universal/src/lib/single-php-instance-manager.ts","../../../../packages/php-wasm/universal/src/lib/php-process-manager.ts","../../../../packages/php-wasm/universal/src/lib/supported-php-versions.ts","../../../../packages/php-wasm/universal/src/lib/urls.ts","../../../../packages/php-wasm/universal/src/lib/encode-as-multipart.ts","../../../../packages/php-wasm/universal/src/lib/php-request-handler.ts","../../../../packages/php-wasm/universal/src/lib/rotate-php-runtime.ts","../../../../packages/php-wasm/universal/src/lib/write-files.ts","../../../../packages/php-wasm/universal/src/lib/proxy-file-system.ts","../../../../packages/php-wasm/universal/src/lib/sandboxed-spawn-handler-factory.ts","../../../../packages/php-wasm/universal/src/lib/comlink-sync.ts","../../../../packages/php-wasm/universal/src/lib/serialize-error.ts","../../../../packages/php-wasm/universal/src/lib/api.ts"],"sourcesContent":["/**\n * Emscripten's filesystem-related Exception.\n *\n * @see https://emscripten.org/docs/api_reference/Filesystem-API.html\n * @see https://github.com/emscripten-core/emscripten/blob/main/system/lib/libc/musl/arch/emscripten/bits/errno.h\n * @see https://github.com/emscripten-core/emscripten/blob/38eedc630f17094b3202fd48ac0c2c585dbea31e/system/include/wasi/api.h#L336\n */\n\nexport class ErrnoError extends Error {\n\tconstructor(errno: number, message?: string, options?: any) {\n\t\tsuper(message, options);\n\t\tthis.name = 'ErrnoError';\n\t\tthis.errno = errno;\n\t}\n\n\tnode?: any;\n\terrno: number;\n}\n/**\n * @see https://github.com/emscripten-core/emscripten/blob/38eedc630f17094b3202fd48ac0c2c585dbea31e/system/include/wasi/api.h#L336\n */\nexport const FileErrorCodes = {\n\t0: 'No error occurred. System call completed successfully.',\n\t1: 'Argument list too long.',\n\t2: 'Permission denied.',\n\t3: 'Address in use.',\n\t4: 'Address not available.',\n\t5: 'Address family not supported.',\n\t6: 'Resource unavailable, or operation would block.',\n\t7: 'Connection already in progress.',\n\t8: 'Bad file descriptor.',\n\t9: 'Bad message.',\n\t10: 'Device or resource busy.',\n\t11: 'Operation canceled.',\n\t12: 'No child processes.',\n\t13: 'Connection aborted.',\n\t14: 'Connection refused.',\n\t15: 'Connection reset.',\n\t16: 'Resource deadlock would occur.',\n\t17: 'Destination address required.',\n\t18: 'Mathematics argument out of domain of function.',\n\t19: 'Reserved.',\n\t20: 'File exists.',\n\t21: 'Bad address.',\n\t22: 'File too large.',\n\t23: 'Host is unreachable.',\n\t24: 'Identifier removed.',\n\t25: 'Illegal byte sequence.',\n\t26: 'Operation in progress.',\n\t27: 'Interrupted function.',\n\t28: 'Invalid argument.',\n\t29: 'I/O error.',\n\t30: 'Socket is connected.',\n\t31: 'There is a directory under that path.',\n\t32: 'Too many levels of symbolic links.',\n\t33: 'File descriptor value too large.',\n\t34: 'Too many links.',\n\t35: 'Message too large.',\n\t36: 'Reserved.',\n\t37: 'Filename too long.',\n\t38: 'Network is down.',\n\t39: 'Connection aborted by network.',\n\t40: 'Network unreachable.',\n\t41: 'Too many files open in system.',\n\t42: 'No buffer space available.',\n\t43: 'No such device.',\n\t44: 'There is no such file or directory OR the parent directory does not exist.',\n\t45: 'Executable file format error.',\n\t46: 'No locks available.',\n\t47: 'Reserved.',\n\t48: 'Not enough space.',\n\t49: 'No message of the desired type.',\n\t50: 'Protocol not available.',\n\t51: 'No space left on device.',\n\t52: 'Function not supported.',\n\t53: 'The socket is not connected.',\n\t54: 'Not a directory or a symbolic link to a directory.',\n\t55: 'Directory not empty.',\n\t56: 'State not recoverable.',\n\t57: 'Not a socket.',\n\t58: 'Not supported, or operation not supported on socket.',\n\t59: 'Inappropriate I/O control operation.',\n\t60: 'No such device or address.',\n\t61: 'Value too large to be stored in data type.',\n\t62: 'Previous owner died.',\n\t63: 'Operation not permitted.',\n\t64: 'Broken pipe.',\n\t65: 'Protocol error.',\n\t66: 'Protocol not supported.',\n\t67: 'Protocol wrong type for socket.',\n\t68: 'Result too large.',\n\t69: 'Read-only file system.',\n\t70: 'Invalid seek.',\n\t71: 'No such process.',\n\t72: 'Reserved.',\n\t73: 'Connection timed out.',\n\t74: 'Text file busy.',\n\t75: 'Cross-device link.',\n\t76: 'Extension: Capabilities insufficient.',\n} as any;\n\nexport function getEmscriptenFsError(e: any) {\n\tconst errno = typeof e === 'object' ? ((e as any)?.errno as any) : null;\n\tif (errno in FileErrorCodes) {\n\t\treturn FileErrorCodes[errno];\n\t}\n}\n\nexport function rethrowFileSystemError(messagePrefix = '') {\n\treturn function catchFileSystemError(value: (...args: any[]) => any) {\n\t\treturn function (...args: any[]) {\n\t\t\ttry {\n\t\t\t\t// @ts-expect-error Parameter 'this' implicitly has an 'any' type.ts(7006)\n\t\t\t\treturn value.apply(this, args);\n\t\t\t} catch (e) {\n\t\t\t\tconst errno =\n\t\t\t\t\ttypeof e === 'object' ? ((e as any)?.errno as any) : null;\n\t\t\t\tif (errno in FileErrorCodes) {\n\t\t\t\t\tconst errmsg = FileErrorCodes[errno];\n\t\t\t\t\tconst path = typeof args[1] === 'string' ? args[1] : null;\n\t\t\t\t\tconst formattedPrefix =\n\t\t\t\t\t\tpath !== null\n\t\t\t\t\t\t\t? messagePrefix.replaceAll('{path}', path)\n\t\t\t\t\t\t\t: messagePrefix;\n\t\t\t\t\tthrow new ErrnoError(\n\t\t\t\t\t\terrno,\n\t\t\t\t\t\t`${formattedPrefix}: ${errmsg}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: e,\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t};\n\t};\n}\n","import type { Emscripten } from './emscripten-types';\nimport {\n\tErrnoError,\n\tgetEmscriptenFsError,\n\trethrowFileSystemError,\n} from './rethrow-file-system-error';\nimport { logger } from '@php-wasm/logger';\nimport { dirname, joinPaths } from '@php-wasm/util';\n\nexport interface RmDirOptions {\n\t/**\n\t * If true, recursively removes the directory and all its contents.\n\t * Default: true.\n\t */\n\trecursive?: boolean;\n}\n\nexport interface ListFilesOptions {\n\t/**\n\t * If true, prepend given folder path to all file names.\n\t * Default: false.\n\t */\n\tprependPath: boolean;\n}\n\nexport class FSHelpers {\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as a string.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param FS\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\tstatic readFileAsText(FS: Emscripten.RootFS, path: string) {\n\t\treturn new TextDecoder().decode(FSHelpers.readFileAsBuffer(FS, path));\n\t}\n\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as an array buffer.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param FS\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\tstatic readFileAsBuffer(FS: Emscripten.RootFS, path: string): Uint8Array {\n\t\treturn FS.readFile(path);\n\t}\n\n\t/**\n\t * Overwrites data in a file in the PHP filesystem.\n\t * Creates a new file if one doesn't exist yet.\n\t *\n\t * @param FS\n\t * @param path - The file path to write to.\n\t * @param data - The data to write to the file.\n\t */\n\tstatic writeFile(\n\t\tFS: Emscripten.RootFS,\n\t\tpath: string,\n\t\tdata: string | Uint8Array | Buffer\n\t) {\n\t\tFS.writeFile(path, data);\n\t}\n\n\t/**\n\t * Removes a file from the PHP filesystem.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param FS\n\t * @param path - The file path to remove.\n\t */\n\tstatic unlink(FS: Emscripten.RootFS, path: string) {\n\t\tFS.unlink(path);\n\t}\n\n\t/**\n\t * Moves a file or directory in the PHP filesystem to a\n\t * new location.\n\t *\n\t * @param FS\n\t * @param fromPath The path to rename.\n\t * @param toPath The new path.\n\t */\n\tstatic mv(FS: Emscripten.RootFS, fromPath: string, toPath: string) {\n\t\ttry {\n\t\t\t// FS.rename moves the inode within the same filesystem.\n\t\t\t// If fromPath and toPath are on different filesystems,\n\t\t\t// the operation will fail. In that case, we need to do\n\t\t\t// a recursive copy of all the files and remove the original.\n\t\t\t// Note this is also what happens in the linux `mv` command.\n\t\t\tconst fromMount = FS.lookupPath(fromPath).node.mount;\n\t\t\tconst toMount = FSHelpers.fileExists(FS, toPath)\n\t\t\t\t? FS.lookupPath(toPath).node.mount\n\t\t\t\t: FS.lookupPath(dirname(toPath)).node.mount;\n\t\t\tconst movingBetweenFilesystems =\n\t\t\t\tfromMount.mountpoint !== toMount.mountpoint;\n\n\t\t\tif (movingBetweenFilesystems) {\n\t\t\t\tFSHelpers.copyRecursive(FS, fromPath, toPath);\n\t\t\t\tif (FSHelpers.isDir(FS, fromPath)) {\n\t\t\t\t\tFSHelpers.rmdir(FS, fromPath, { recursive: true });\n\t\t\t\t} else {\n\t\t\t\t\tFS.unlink(fromPath);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tFS.rename(fromPath, toPath);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconst errmsg = getEmscriptenFsError(e);\n\t\t\tif (!errmsg) {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Could not move ${fromPath} to ${toPath}: ${errmsg}`,\n\t\t\t\t{\n\t\t\t\t\tcause: e,\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Removes a directory from the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path The directory path to remove.\n\t * @param options Options for the removal.\n\t */\n\tstatic rmdir(\n\t\tFS: Emscripten.RootFS,\n\t\tpath: string,\n\t\toptions: RmDirOptions = { recursive: true }\n\t) {\n\t\t/**\n\t\t * Mount points cannot be removed and will throw a ErrnoError with\n\t\t * the code 10 (EBUSY).\n\t\t * To prevent the recursive option from removing internal files before\n\t\t * failing to remove the mount point, we need to check if the path is a\n\t\t * mount point and throw an error early.\n\t\t *\n\t\t * Because a mountpoint can be a symlink, we should not follow it.\n\t\t * Otherwise, a mounted sylink would point to the symlinked path,\n\t\t * instead of the mountpoint.\n\t\t */\n\t\tconst mountPoint = FS.lookupPath(path, { follow: false });\n\t\tif (mountPoint?.node.mount.mountpoint === path) {\n\t\t\tthrow new ErrnoError(10);\n\t\t}\n\n\t\tif (options?.recursive) {\n\t\t\tFSHelpers.listFiles(FS, path).forEach((file) => {\n\t\t\t\tconst filePath = `${path}/${file}`;\n\t\t\t\tif (FSHelpers.isDir(FS, filePath)) {\n\t\t\t\t\tFSHelpers.rmdir(FS, filePath, options);\n\t\t\t\t} else {\n\t\t\t\t\tFSHelpers.unlink(FS, filePath);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (FS.getPath(FS.lookupPath(path).node) === FS.cwd()) {\n\t\t\tFS.chdir(joinPaths(FS.cwd(), '..'));\n\t\t}\n\t\tFS.rmdir(path);\n\t}\n\n\t/**\n\t * Lists the files and directories in the given directory.\n\t *\n\t * @param FS\n\t * @param path - The directory path to list.\n\t * @param options - Options for the listing.\n\t * @returns The list of files and directories in the given directory.\n\t */\n\tstatic listFiles(\n\t\tFS: Emscripten.RootFS,\n\t\tpath: string,\n\t\toptions: ListFilesOptions = { prependPath: false }\n\t): string[] {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn [];\n\t\t}\n\t\ttry {\n\t\t\tconst files = FS.readdir(path).filter(\n\t\t\t\t(name: string) => name !== '.' && name !== '..'\n\t\t\t);\n\t\t\tif (options.prependPath) {\n\t\t\t\tconst prepend = path.replace(/\\/$/, '');\n\t\t\t\treturn files.map((name: string) => `${prepend}/${name}`);\n\t\t\t}\n\t\t\treturn files;\n\t\t} catch (e) {\n\t\t\tlogger.error(e, { path });\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a directory exists in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path – The path to check.\n\t * @returns True if the path is a directory, false otherwise.\n\t */\n\tstatic isDir(FS: Emscripten.RootFS, path: string): boolean {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn FS.isDir(FS.lookupPath(path, { follow: true }).node.mode);\n\t}\n\n\t/**\n\t * Checks if a file exists in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path – The path to check.\n\t * @returns True if the path is a file, false otherwise.\n\t */\n\tstatic isFile(FS: Emscripten.RootFS, path: string): boolean {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn FS.isFile(FS.lookupPath(path, { follow: true }).node.mode);\n\t}\n\n\t/**\n\t * Creates a symlink in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param target\n\t * @param link\n\t */\n\tstatic symlink(FS: Emscripten.RootFS, target: string, link: string): any {\n\t\treturn FS.symlink(target, link);\n\t}\n\n\t/**\n\t * Checks if a path is a symlink in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path\n\t * @returns True if the path is a symlink, false otherwise.\n\t */\n\tstatic isSymlink(FS: Emscripten.RootFS, path: string): boolean {\n\t\tif (!FSHelpers.fileExists(FS, path)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn FS.isLink(FS.lookupPath(path).node.mode);\n\t}\n\n\t/**\n\t * Reads the target of a symlink in the PHP filesystem.\n\t * @param FS\n\t * @param path\n\t * @returns The target of the symlink.\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the path is not a symlink.\n\t */\n\tstatic readlink(FS: Emscripten.RootFS, path: string): string {\n\t\treturn FS.readlink(path);\n\t}\n\n\t/**\n\t * Gets the real path of a file in the PHP filesystem.\n\t * @param FS\n\t * @param path\n\t *\n\t * @returns The real path of the file.\n\t */\n\tstatic realpath(FS: Emscripten.RootFS, path: string): string {\n\t\treturn FS.lookupPath(path, { follow: true }).path;\n\t}\n\n\t/**\n\t * Checks if a file (or a directory) exists in the PHP filesystem.\n\t *\n\t * @param FS\n\t * @param path - The file path to check.\n\t * @returns True if the file exists, false otherwise.\n\t */\n\tstatic fileExists(FS: Emscripten.RootFS, path: string): boolean {\n\t\ttry {\n\t\t\tFS.lookupPath(path);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Recursively creates a directory with the given path in the PHP filesystem.\n\t * For example, if the path is `/root/php/data`, and `/root` already exists,\n\t * it will create the directories `/root/php` and `/root/php/data`.\n\t *\n\t * @param FS\n\t * @param path - The directory path to create.\n\t */\n\tstatic mkdir(FS: Emscripten.RootFS, path: string) {\n\t\tFS.mkdirTree(path);\n\t}\n\n\tstatic copyRecursive(\n\t\tFS: Emscripten.FileSystemInstance,\n\t\tfromPath: string,\n\t\ttoPath: string\n\t) {\n\t\tconst fromNode = FS.lookupPath(fromPath).node;\n\t\tif (FS.isDir(fromNode.mode)) {\n\t\t\tFS.mkdirTree(toPath);\n\t\t\tconst filenames = FS.readdir(fromPath).filter(\n\t\t\t\t(name: string) => name !== '.' && name !== '..'\n\t\t\t);\n\t\t\tfor (const filename of filenames) {\n\t\t\t\tFSHelpers.copyRecursive(\n\t\t\t\t\tFS,\n\t\t\t\t\tjoinPaths(fromPath, filename),\n\t\t\t\t\tjoinPaths(toPath, filename)\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (FS.isLink(fromNode.mode)) {\n\t\t\tFS.symlink(FS.readlink(fromPath), toPath);\n\t\t} else {\n\t\t\tFS.writeFile(toPath, FS.readFile(fromPath));\n\t\t}\n\t}\n}\n\n// Apply decorators manually until the decorator syntax is supported\n// by Node.js. We do this so we can take advantage of Node.js type stripping\n// in the meantime.\n// TODO: Inline these decorators once Node.js supports it.\nFSHelpers.readFileAsText = rethrowFileSystemError('Could not read \"{path}\"')(\n\tFSHelpers.readFileAsText\n);\nFSHelpers.readFileAsBuffer = rethrowFileSystemError('Could not read \"{path}\"')(\n\tFSHelpers.readFileAsBuffer\n);\nFSHelpers.writeFile = rethrowFileSystemError('Could not write to \"{path}\"')(\n\tFSHelpers.writeFile\n);\nFSHelpers.unlink = rethrowFileSystemError('Could not unlink \"{path}\"')(\n\tFSHelpers.unlink\n);\nFSHelpers.rmdir = rethrowFileSystemError('Could not remove directory \"{path}\"')(\n\tFSHelpers.rmdir\n);\nFSHelpers.listFiles = rethrowFileSystemError(\n\t'Could not list files in \"{path}\"'\n)(FSHelpers.listFiles);\nFSHelpers.isDir = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.isDir\n);\nFSHelpers.isFile = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.isFile\n);\nFSHelpers.realpath = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.realpath\n);\nFSHelpers.fileExists = rethrowFileSystemError('Could not stat \"{path}\"')(\n\tFSHelpers.fileExists\n);\nFSHelpers.mkdir = rethrowFileSystemError('Could not create directory \"{path}\"')(\n\tFSHelpers.mkdir\n);\nFSHelpers.copyRecursive = rethrowFileSystemError(\n\t'Could not copy files from \"{path}\"'\n)(FSHelpers.copyRecursive);\n","import type { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type { ListFilesOptions, RmDirOptions } from './fs-helpers';\nimport type { PHP } from './php';\nimport type { PHPRequestHandler } from './php-request-handler';\nimport type { PHPResponse, StreamedPHPResponse } from './php-response';\nimport type {\n\tMessageListener,\n\tPHPEvent,\n\tPHPRequest,\n\tPHPRunOptions,\n} from './universal-php';\n\nconst _private = new WeakMap<\n\tPHPWorker,\n\t{\n\t\trequestHandler?: PHPRequestHandler;\n\t\tphp?: PHP;\n\t\tmonitor?: EmscriptenDownloadMonitor;\n\t}\n>();\n\nexport type LimitedPHPApi = Pick<\n\tPHP,\n\t| 'request'\n\t| 'defineConstant'\n\t| 'mkdir'\n\t| 'mkdirTree'\n\t| 'readFileAsText'\n\t| 'readFileAsBuffer'\n\t| 'writeFile'\n\t| 'unlink'\n\t| 'mv'\n\t| 'rmdir'\n\t| 'listFiles'\n\t| 'isDir'\n\t| 'fileExists'\n\t| 'chdir'\n\t| 'run'\n\t| 'onMessage'\n> & {\n\tdocumentRoot: PHP['documentRoot'];\n\tabsoluteUrl: PHP['absoluteUrl'];\n\taddEventListener:\n\t\t| PHP['addEventListener']\n\t\t| ((event: string, listener: (event: any) => any) => void);\n\tremoveEventListener:\n\t\t| PHP['removeEventListener']\n\t\t| ((event: string, listener: (event: any) => any) => void);\n};\n\nexport type PHPWorkerEvent = PHPEvent | { type: string };\nexport type PHPWorkerEventListener = (event: PHPWorkerEvent) => void;\n/**\n * A PHP client that can be used to run PHP code in the browser.\n */\nexport class PHPWorker implements LimitedPHPApi, AsyncDisposable {\n\t/** @inheritDoc @php-wasm/universal!RequestHandler.absoluteUrl */\n\tabsoluteUrl = '';\n\t/** @inheritDoc @php-wasm/universal!RequestHandler.documentRoot */\n\tdocumentRoot = '';\n\n\tprivate chroot: string | null = null;\n\n\t#eventListeners: Map<string, Set<PHPWorkerEventListener>> = new Map();\n\n\tonMessageListeners: MessageListener[] = [];\n\t/** @inheritDoc */\n\tconstructor(\n\t\trequestHandler?: PHPRequestHandler,\n\t\tmonitor?: EmscriptenDownloadMonitor\n\t) {\n\t\t/**\n\t\t * Workaround for TypeScript limitation.\n\t\t * Declaring a private field using the EcmaScript syntax like this:\n\t\t *\n\t\t * #php: PHP\n\t\t *\n\t\t * Makes that field a part of the public API of the class. This means\n\t\t * you can no longer assign seemingly compatible objects:\n\t\t *\n\t\t * ```ts\n\t\t * class PrivateEcma {\n\t\t * #privateProp: string = '';\n\t\t * callback() { }\n\t\t * }\n\t\t * interface CompatibleInterface {\n\t\t * callback(): void;\n\t\t * }\n\t\t * const compatObj: CompatibleInterface = {} as any;\n\t\t * const tsObj: PrivateEcma = compatObj;\n\t\t * // Property '#privateProp' is missing in type 'CompatibleInterface' but\n\t\t * // required in type 'PrivateEcma'\n\t\t * ```\n\t\t */\n\t\t_private.set(this, {\n\t\t\tmonitor,\n\t\t});\n\t\tif (requestHandler) {\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\t\t}\n\t}\n\n\tpublic __internal_setRequestHandler(requestHandler: PHPRequestHandler) {\n\t\tthis.absoluteUrl = requestHandler.absoluteUrl;\n\t\tthis.documentRoot = requestHandler.documentRoot;\n\t\tthis.chroot = this.documentRoot;\n\t\t_private.set(this, {\n\t\t\t..._private.get(this),\n\t\t\trequestHandler,\n\t\t});\n\t}\n\n\t/**\n\t * @internal\n\t * @deprecated\n\t * Do not use this method directly in the code consuming\n\t * the web API. It will change or even be removed without\n\t * a warning.\n\t */\n\tprotected __internal_getPHP() {\n\t\treturn _private.get(this)!.php;\n\t}\n\n\t/**\n\t * @internal\n\t * @deprecated\n\t * Do not use this method directly in the code consuming\n\t * the web API. It will change or even be removed without\n\t * a warning.\n\t */\n\tprotected __internal_getRequestHandler() {\n\t\treturn _private.get(this)!.requestHandler;\n\t}\n\n\tasync setPrimaryPHP(php: PHP) {\n\t\t_private.set(this, {\n\t\t\t..._private.get(this)!,\n\t\t\tphp,\n\t\t});\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHPRequestHandler.pathToInternalUrl */\n\tpathToInternalUrl(path: string): string {\n\t\treturn _private.get(this)!.requestHandler!.pathToInternalUrl(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHPRequestHandler.internalUrlToPath */\n\tinternalUrlToPath(internalUrl: string): string {\n\t\treturn _private\n\t\t\t.get(this)!\n\t\t\t.requestHandler!.internalUrlToPath(internalUrl);\n\t}\n\n\t/**\n\t * The onDownloadProgress event listener.\n\t */\n\tasync onDownloadProgress(\n\t\tcallback: (progress: CustomEvent<ProgressEvent>) => void\n\t): Promise<void> {\n\t\treturn _private\n\t\t\t.get(this)!\n\t\t\t.monitor?.addEventListener('progress', callback as any);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHP.mv */\n\tasync mv(fromPath: string, toPath: string) {\n\t\treturn _private.get(this)!.php!.mv(fromPath, toPath);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHP.rmdir */\n\tasync rmdir(path: string, options?: RmDirOptions) {\n\t\treturn _private.get(this)!.php!.rmdir(path, options);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!PHPRequestHandler.request */\n\tasync request(request: PHPRequest): Promise<PHPResponse> {\n\t\tconst requestHandler = _private.get(this)!.requestHandler!;\n\t\treturn await requestHandler.request(request);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.run */\n\tasync run(request: PHPRunOptions): Promise<PHPResponse> {\n\t\tconst { php, reap } = await this.acquirePHPInstance();\n\t\ttry {\n\t\t\treturn await php.run(request);\n\t\t} finally {\n\t\t\treap();\n\t\t}\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.cli */\n\tasync cli(\n\t\targv: string[],\n\t\toptions?: { env?: Record<string, string> }\n\t): Promise<StreamedPHPResponse> {\n\t\tconst { php, reap } = await this.acquirePHPInstance();\n\t\tlet response: StreamedPHPResponse;\n\t\ttry {\n\t\t\tresponse = await php.cli(argv, options);\n\t\t} catch (error) {\n\t\t\treap();\n\t\t\tthrow error;\n\t\t}\n\t\t/**\n\t\t * Register the reap() callback to run asynchronously once\n\t\t * the response is finished.\n\t\t *\n\t\t * We don't await for response.finished here. It is a\n\t\t * `StreamedPHPResponse` instance and the caller may want\n\t\t * to start processing the streamed data immediately.\n\t\t */\n\t\tresponse.finished.finally(reap);\n\t\treturn response;\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.chdir */\n\tchdir(path: string): void {\n\t\t// Remember the new chroot for all PHP instances yet to be acquired.\n\t\tthis.chroot = path;\n\t\treturn _private.get(this)!.php!.chdir(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.chdir */\n\tcwd(): string {\n\t\treturn _private.get(this)!.php!.cwd();\n\t}\n\n\t/**\n\t * @returns A PHP instance with a consistent chroot.\n\t */\n\tprivate async acquirePHPInstance() {\n\t\tconst { php, reap } = await _private\n\t\t\t.get(this)!\n\t\t\t.requestHandler!.instanceManager.acquirePHPInstance();\n\t\tif (this.chroot !== null) {\n\t\t\tphp.chdir(this.chroot);\n\t\t}\n\t\tthis.registerWorkerListeners(php);\n\t\treturn { php, reap };\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.setSapiName */\n\tsetSapiName(newName: string): void {\n\t\t_private.get(this)!.php!.setSapiName(newName);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.mkdir */\n\tmkdir(path: string): void {\n\t\treturn _private.get(this)!.php!.mkdir(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.mkdirTree */\n\tmkdirTree(path: string): void {\n\t\treturn _private.get(this)!.php!.mkdirTree(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.readFileAsText */\n\treadFileAsText(path: string): string {\n\t\treturn _private.get(this)!.php!.readFileAsText(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.readFileAsBuffer */\n\treadFileAsBuffer(path: string): Uint8Array {\n\t\treturn _private.get(this)!.php!.readFileAsBuffer(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.writeFile */\n\twriteFile(path: string, data: string | Uint8Array): void {\n\t\treturn _private.get(this)!.php!.writeFile(path, data);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.unlink */\n\tunlink(path: string): void {\n\t\treturn _private.get(this)!.php!.unlink(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.listFiles */\n\tlistFiles(path: string, options?: ListFilesOptions): string[] {\n\t\treturn _private.get(this)!.php!.listFiles(path, options);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.isDir */\n\tisDir(path: string): boolean {\n\t\treturn _private.get(this)!.php!.isDir(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.isFile */\n\tisFile(path: string): boolean {\n\t\treturn _private.get(this)!.php!.isFile(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.fileExists */\n\tfileExists(path: string): boolean {\n\t\treturn _private.get(this)!.php!.fileExists(path);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.onMessage */\n\tonMessage(listener: MessageListener) {\n\t\tthis.onMessageListeners.push(listener);\n\t\treturn async () => {\n\t\t\tthis.onMessageListeners = this.onMessageListeners.filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t};\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.defineConstant */\n\tdefineConstant(key: string, value: string | boolean | number | null): void {\n\t\t_private.get(this)!.php!.defineConstant(key, value);\n\t}\n\n\t/** @inheritDoc @php-wasm/universal!/PHP.addEventListener */\n\taddEventListener(\n\t\teventType: PHPWorkerEvent['type'],\n\t\tlistener: PHPWorkerEventListener\n\t): void {\n\t\tif (!this.#eventListeners.has(eventType)) {\n\t\t\tthis.#eventListeners.set(eventType, new Set());\n\t\t}\n\t\tthis.#eventListeners.get(eventType)!.add(listener);\n\t}\n\n\t/**\n\t * Removes an event listener for a PHP event.\n\t * @param eventType - The type of event to remove the listener from.\n\t * @param listener - The listener function to be removed.\n\t */\n\tremoveEventListener(\n\t\teventType: PHPWorkerEvent['type'],\n\t\tlistener: PHPWorkerEventListener\n\t) {\n\t\tthis.#eventListeners.get(eventType)?.delete(listener);\n\t}\n\n\tprotected dispatchEvent<Event extends PHPWorkerEvent>(event: Event) {\n\t\tconst listeners = this.#eventListeners.get(event.type);\n\t\tif (!listeners) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const listener of listeners) {\n\t\t\tlistener(event);\n\t\t}\n\t}\n\n\tprotected registerWorkerListeners(php: PHP) {\n\t\tphp.addEventListener('*', async (event) => {\n\t\t\tthis.dispatchEvent(event);\n\t\t});\n\t\tphp.onMessage(async (message) => {\n\t\t\tfor (const listener of this.onMessageListeners) {\n\t\t\t\tconst returnData = await listener(message);\n\t\t\t\tif (returnData) {\n\t\t\t\t\treturn returnData;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn '';\n\t\t});\n\t}\n\n\tasync [Symbol.asyncDispose]() {\n\t\tawait _private.get(this)!.requestHandler?.[Symbol.asyncDispose]();\n\t}\n}\n","/**\n * Check if the Emscripten-thrown error is an exit code 0 error.\n *\n * @param e The error to check\n * @returns True if the error appears to represent an exit code or status\n */\nexport function isExitCode(e: any): e is { status: number } {\n\tif (!(e instanceof Error)) {\n\t\treturn false;\n\t}\n\treturn e?.name === 'ExitStatus' && 'status' in e;\n}\n","import { logger } from '@php-wasm/logger';\nimport type { IncomingMessage, Server, ServerResponse } from 'http';\n\nconst RuntimeId = Symbol('RuntimeId');\nconst loadedRuntimes: Map<number, PHPRuntime> = new Map();\nlet lastRuntimeId = 0;\n\n/**\n * Loads the PHP runtime with the given arguments and data dependencies.\n *\n * This function handles the entire PHP initialization pipeline. In particular,\n * it:\n *\n * * Instantiates the Emscripten PHP module\n * * Wires it together with the data dependencies and loads them\n * * Ensures is all happens in a correct order\n * * Waits until the entire loading sequence is finished\n *\n * Basic usage:\n *\n * ```js\n * const phpLoaderModule = await getPHPLoaderModule(\"7.4\");\n * const php = await loadPHPRuntime( phpLoaderModule );\n * console.log(php.run(`<?php echo \"Hello, world!\"; `));\n * // { stdout: ArrayBuffer containing the string \"Hello, world!\", stderr: [''], exitCode: 0 }\n * ```\n *\n * **The PHP loader module:**\n *\n * In the basic usage example, `phpLoaderModule` is **not** a vanilla\n * Emscripten module. Instead, it's an ESM module that wraps the regular\n * Emscripten output and adds some extra functionality. It's generated by the\n * Dockerfile shipped with this repo. Here's the API it provides:\n *\n * ```js\n * // php.wasm size in bytes:\n * export const dependenciesTotalSize = 5644199;\n *\n * // php.wasm filename:\n * export const dependencyFilename = 'php.wasm';\n *\n * // Run Emscripten's generated module:\n * export default function(jsEnv, emscriptenModuleArgs) {}\n * ```\n *\n * **PHP Filesystem:**\n *\n * Once initialized, the PHP has its own filesystem separate from the project\n * files. It's provided by [Emscripten and uses its FS library](https://emscripten.org/docs/api_reference/Filesystem-API.html).\n *\n * The API exposed to you via the PHP class is succinct and abstracts\n * certain unintuitive parts of low-level filesystem interactions.\n *\n * Here's how to use it:\n *\n * ```js\n * // Recursively create a /var/www directory\n * php.mkdirTree('/var/www');\n *\n * console.log(php.fileExists('/var/www/file.txt'));\n * // false\n *\n * php.writeFile('/var/www/file.txt', 'Hello from the filesystem!');\n *\n * console.log(php.fileExists('/var/www/file.txt'));\n * // true\n *\n * console.log(php.readFile('/var/www/file.txt'));\n * // \"Hello from the filesystem!\n *\n * // Delete the file:\n * php.unlink('/var/www/file.txt');\n * ```\n *\n * For more details consult the PHP class directly.\n *\n * **Data dependencies:**\n *\n * Using existing PHP packages by manually recreating them file-by-file would\n * be quite inconvenient. Fortunately, Emscripten provides a \"data dependencies\"\n * feature.\n *\n * Data dependencies consist of a `dependency.data` file and a `dependency.js`\n * loader and can be packaged with the [file_packager.py tool](\n * https://emscripten.org/docs/porting/files/packaging_files.html#packaging-using-the-file-packager-tool).\n * This project requires wrapping the Emscripten-generated `dependency.js` file\n * in an ES module as follows:\n *\n * 1. Prepend `export default function(emscriptenPHPModule) {'; `\n * 2. Prepend `export const dependencyFilename = '<DATA FILE NAME>'; `\n * 3. Prepend `export const dependenciesTotalSize = <DATA FILE SIZE>;`\n * 4. Append `}`\n *\n * Be sure to use the `--export-name=\"emscriptenPHPModule\"` file_packager.py\n * option.\n *\n * You want the final output to look as follows:\n *\n * ```js\n * export const dependenciesTotalSize = 5644199;\n * export const dependencyFilename = 'dependency.data';\n * export default function(emscriptenPHPModule) {\n * // Emscripten-generated code:\n * var Module = typeof emscriptenPHPModule !== 'undefined' ? emscriptenPHPModule : {};\n * // ... the rest of it ...\n * }\n * ```\n *\n * Such a constructions enables loading the `dependency.js` as an ES Module\n * using `import(\"/dependency.js\")`.\n *\n * Once it's ready, you can load PHP and your data dependencies as follows:\n *\n * ```js\n * const [phpLoaderModule, wordPressLoaderModule] = await Promise.all([\n * getPHPLoaderModule(\"7.4\"),\n * import(\"/wp.js\")\n * ]);\n * const php = await loadPHPRuntime(phpLoaderModule, {}, [wordPressLoaderModule]);\n * ```\n *\n * @public\n * @param phpLoaderModule - The ESM-wrapped Emscripten module. Consult the Dockerfile for the build process.\n * @param options - The Emscripten module arguments, see https://emscripten.org/docs/api_reference/module.html#affecting-execution.\n * @returns Loaded runtime id.\n */\n\nexport async function loadPHPRuntime(\n\tphpLoaderModule: PHPLoaderModule,\n\t...options: EmscriptenOptions[]\n): Promise<number> {\n\tconst phpModuleArgs = Object.assign({}, ...options);\n\n\tconst [phpReady, resolvePHP, rejectPHP] = makePromise();\n\n\tconst PHPRuntime = phpLoaderModule.init(currentJsRuntime, {\n\t\tonAbort(reason) {\n\t\t\trejectPHP(reason);\n\t\t\t// This can happen after PHP has been initialized so\n\t\t\t// let's just log it.\n\t\t\tlogger.error(reason);\n\t\t},\n\t\tENV: {},\n\t\t// Emscripten sometimes prepends a '/' to the path, which\n\t\t// breaks vite dev mode. An identity `locateFile` function\n\t\t// fixes it.\n\t\tlocateFile: (path) => path,\n\t\t...phpModuleArgs,\n\t\tnoInitialRun: true,\n\t\tonRuntimeInitialized() {\n\t\t\tif (phpModuleArgs.onRuntimeInitialized) {\n\t\t\t\tphpModuleArgs.onRuntimeInitialized(PHPRuntime);\n\t\t\t}\n\t\t\tresolvePHP();\n\t\t},\n\t});\n\n\tawait phpReady;\n\n\tconst id = ++lastRuntimeId;\n\n\t// TODO: Ask @adamziel why this is here.\n\t// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- why is this here?\n\tPHPRuntime.FS;\n\tPHPRuntime.id = id;\n\tPHPRuntime.originalExit = PHPRuntime._exit;\n\n\tPHPRuntime._exit = function (code: number) {\n\t\tif (PHPRuntime.outboundNetworkProxyServer) {\n\t\t\tPHPRuntime.outboundNetworkProxyServer.close();\n\t\t\tPHPRuntime.outboundNetworkProxyServer.closeAllConnections();\n\t\t}\n\t\tloadedRuntimes.delete(id);\n\t\treturn PHPRuntime.originalExit(code);\n\t};\n\n\tPHPRuntime[RuntimeId] = id;\n\tloadedRuntimes.set(id, PHPRuntime);\n\treturn id;\n}\n\nexport type RuntimeType = 'NODE' | 'WEB' | 'WORKER';\n\ndeclare const self: WindowOrWorkerGlobalScope;\ndeclare const WorkerGlobalScope: object | undefined;\n\nexport type PHPRuntimeId = number;\n\n/**\n * Retrieves a PHP runtime by its ID and removes it from the internal registry.\n *\n * When you call `loadPHPRuntime()`, it creates an Emscripten-based PHP instance and\n * stores it in a module-level Map keyed by a numeric ID. This function is the only\n * way to retrieve that runtime object so you can actually use it.\n *\n * The \"pop\" semantic is intentional: retrieving a runtime also removes it from the\n * registry. This prevents memory leaks since the registry would otherwise hold\n * references to every runtime ever created. Once you pop a runtime, you own it and\n * are responsible for its lifecycle.\n *\n * Typical usage flow:\n * ```ts\n * // 1. Load a PHP runtime (returns just the ID)\n * const runtimeId = await loadPHPRuntime(phpLoaderModule);\n *\n * // 2. Pop the runtime to get the actual Emscripten module\n * const phpRuntime = popLoadedRuntime(runtimeId);\n *\n * // 3. Now you can use phpRuntime to run PHP code, access the filesystem, etc.\n * ```\n *\n * @param id - The numeric ID returned by `loadPHPRuntime()`.\n * @param options.dangerouslyKeepTheRuntimeInTheMap - Test-only escape hatch. When true,\n * retrieves the runtime without removing it from the registry. This violates\n * the function's contract and only works when `process.env.TEST` is set.\n * Never use this in production code.\n * @returns The PHP runtime object (an Emscripten module instance).\n * @throws If no runtime exists with the given ID.\n */\nexport function popLoadedRuntime(\n\tid: PHPRuntimeId,\n\t{\n\t\tdangerouslyKeepTheRuntimeInTheMap = false,\n\t}: { dangerouslyKeepTheRuntimeInTheMap?: boolean } = {}\n): PHPRuntime {\n\tconst runtime = loadedRuntimes.get(id);\n\tif (!runtime) {\n\t\tthrow new Error(`Runtime with id ${id} not found`);\n\t}\n\tif (dangerouslyKeepTheRuntimeInTheMap) {\n\t\tif (!process?.env?.['TEST']) {\n\t\t\tthrow new Error('Cannot pop runtime in non-test environment');\n\t\t}\n\t\treturn runtime;\n\t}\n\n\tloadedRuntimes.delete(id);\n\treturn runtime;\n}\n\nexport const currentJsRuntime = (function () {\n\tif (typeof process !== 'undefined' && process.release?.name === 'node') {\n\t\treturn 'NODE';\n\t} else if (typeof window !== 'undefined') {\n\t\treturn 'WEB';\n\t} else if (\n\t\ttypeof WorkerGlobalScope !== 'undefined' &&\n\t\tself instanceof (WorkerGlobalScope as any)\n\t) {\n\t\treturn 'WORKER';\n\t} else {\n\t\treturn 'NODE';\n\t}\n})();\n\n/**\n * Creates and exposes Promise resolve/reject methods for later use.\n */\nconst makePromise = () => {\n\tconst methods: any = [];\n\n\tconst promise = new Promise((resolve, reject) => {\n\t\tmethods.push(resolve, reject);\n\t});\n\tmethods.unshift(promise);\n\n\treturn methods as [Promise<any>, (v?: any) => void, (e?: any) => void];\n};\n\nexport type PHPRuntime = any;\n\nexport type PHPLoaderModule = {\n\tdependencyFilename: string;\n\tdependenciesTotalSize: number;\n\tinit: (jsRuntime: string, options: EmscriptenOptions) => PHPRuntime;\n};\n\nexport type DataModule = {\n\tdependencyFilename: string;\n\tdependenciesTotalSize: number;\n\tdefault: (phpRuntime: PHPRuntime) => void;\n};\n\nexport type EmscriptenOptions = {\n\tonAbort?: (message: string) => void;\n\t/**\n\t * Set to true for debugging tricky WebAssembly errors.\n\t */\n\tdebug?: boolean;\n\tENV?: Record<string, string>;\n\tlocateFile?: (path: string) => string;\n\tnoInitialRun?: boolean;\n\tprint?: (message: string) => void;\n\tprintErr?: (message: string) => void;\n\tquit?: (status: number, toThrow: any) => void;\n\tonRuntimeInitialized?: (phpRuntime: PHPRuntime) => void;\n\tmonitorRunDependencies?: (left: number) => void;\n\tonMessage?: (listener: EmscriptenMessageListener) => void;\n\toutboundNetworkProxyServer?: Server<\n\t\ttypeof IncomingMessage,\n\t\ttypeof ServerResponse\n\t>;\n\tinstantiateWasm?: (\n\t\tinfo: WebAssembly.Imports,\n\t\treceiveInstance: (\n\t\t\tinstance: WebAssembly.Instance,\n\t\t\tmodule: WebAssembly.Module\n\t\t) => void\n\t) => void;\n} & Record<string, any>;\n\nexport type EmscriptenMessageListener = (type: string, data: string) => void;\n","/*\n * This type is used in Comlink.transferHandlers.set('PHPResponse', { ... })\n * so be sure to update that if you change this type.\n */\nexport interface PHPResponseData {\n\t/**\n\t * Response headers.\n\t */\n\treadonly headers: Record<string, string[]>;\n\n\t/**\n\t * Response body. Contains the output from `echo`,\n\t * `print`, inline HTML etc.\n\t */\n\treadonly bytes: Uint8Array;\n\n\t/**\n\t * Stderr contents, if any.\n\t */\n\treadonly errors: string;\n\n\t/**\n\t * The exit code of the script. `0` is a success, while\n\t * `1` and `2` indicate an error.\n\t */\n\treadonly exitCode: number;\n\n\t/**\n\t * Response HTTP status code, e.g. 200.\n\t */\n\treadonly httpStatusCode: number;\n}\n\nconst responseTexts: Record<number, string> = {\n\t500: 'Internal Server Error',\n\t502: 'Bad Gateway',\n\t404: 'Not Found',\n\t403: 'Forbidden',\n\t401: 'Unauthorized',\n\t400: 'Bad Request',\n\t301: 'Moved Permanently',\n\t302: 'Found',\n\t307: 'Temporary Redirect',\n\t308: 'Permanent Redirect',\n\t204: 'No Content',\n\t201: 'Created',\n\t200: 'OK',\n};\n\nexport class StreamedPHPResponse {\n\t/**\n\t * Response headers.\n\t */\n\tprivate readonly headersStream: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Response body. Contains the output from `echo`,\n\t * `print`, inline HTML etc.\n\t */\n\treadonly stdout: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Stderr contents, if any.\n\t */\n\treadonly stderr: ReadableStream<Uint8Array>;\n\n\t/**\n\t * The exit code of the script. `0` is a success, anything\n\t * else is an error.\n\t */\n\treadonly exitCode: Promise<number>;\n\n\tprivate parsedHeaders: Promise<{\n\t\theaders: Record<string, string[]>;\n\t\thttpStatusCode: number;\n\t}> | null = null;\n\n\tprivate cachedStdoutBytes: Promise<Uint8Array> | null = null;\n\tprivate cachedStderrText: Promise<string> | null = null;\n\n\tconstructor(\n\t\theaders: ReadableStream<Uint8Array>,\n\t\tstdout: ReadableStream<Uint8Array>,\n\t\tstderr: ReadableStream<Uint8Array>,\n\t\texitCode: Promise<number>\n\t) {\n\t\tthis.headersStream = headers;\n\t\tthis.stdout = stdout;\n\t\tthis.stderr = stderr;\n\t\tthis.exitCode = exitCode;\n\t}\n\n\t/**\n\t * True if the response is successful (HTTP status code 200-399),\n\t * false otherwise.\n\t */\n\tasync ok(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst statusCode = await this.httpStatusCode;\n\t\t\treturn statusCode >= 200 && statusCode < 400;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Resolves when the response has finished processing – either successfully or not.\n\t */\n\tget finished(): Promise<void> {\n\t\treturn Promise.allSettled([this.exitCode.finally(() => {})]).then(\n\t\t\t() => {}\n\t\t);\n\t}\n\n\t/**\n\t * Resolves once HTTP headers are available.\n\t */\n\tget headers(): Promise<Record<string, string[]>> {\n\t\treturn this.getParsedHeaders().then((headers) => headers.headers);\n\t}\n\n\t/**\n\t * Resolves once HTTP status code is available.\n\t */\n\tget httpStatusCode(): Promise<number> {\n\t\treturn this.getParsedHeaders()\n\t\t\t.then((headers) => headers.httpStatusCode)\n\t\t\t.then((result) => {\n\t\t\t\tif (result !== undefined) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\t// If exit code is 0 or not available yet, fall back to parsed headers\n\t\t\t\treturn this.getParsedHeaders().then(\n\t\t\t\t\t(headers) => headers.httpStatusCode,\n\t\t\t\t\t() => 200\n\t\t\t\t);\n\t\t\t})\n\t\t\t.catch(() => 500);\n\t}\n\n\t/**\n\t * Exposes the stdout bytes as they're produced by the PHP instance\n\t */\n\tget stdoutText(): Promise<string> {\n\t\treturn this.stdoutBytes.then((bytes) =>\n\t\t\tnew TextDecoder().decode(bytes)\n\t\t);\n\t}\n\n\t/**\n\t * Exposes the stdout bytes as they're produced by the PHP instance\n\t */\n\tget stdoutBytes(): Promise<Uint8Array> {\n\t\tif (!this.cachedStdoutBytes) {\n\t\t\tthis.cachedStdoutBytes = streamToBytes(this.stdout);\n\t\t}\n\t\treturn this.cachedStdoutBytes;\n\t}\n\n\t/**\n\t * Exposes the stderr bytes as they're produced by the PHP instance\n\t */\n\tget stderrText(): Promise<string> {\n\t\tif (!this.cachedStderrText) {\n\t\t\tthis.cachedStderrText = streamToText(this.stderr);\n\t\t}\n\t\treturn this.cachedStderrText;\n\t}\n\n\tprivate async getParsedHeaders() {\n\t\tif (!this.parsedHeaders) {\n\t\t\tthis.parsedHeaders = parseHeadersStream(this.headersStream);\n\t\t}\n\t\treturn await this.parsedHeaders;\n\t}\n}\n\nasync function parseHeadersStream(\n\theadersStream: ReadableStream<Uint8Array>\n): Promise<{\n\theaders: Record<string, string[]>;\n\thttpStatusCode: number;\n}> {\n\tconst headersText = await streamToText(headersStream);\n\tlet headersData;\n\ttry {\n\t\theadersData = JSON.parse(headersText);\n\t} catch {\n\t\treturn { headers: {}, httpStatusCode: 200 };\n\t}\n\tconst headers: PHPResponse['headers'] = {};\n\tfor (const line of headersData.headers) {\n\t\t// Skip invalid response headers and the last \"__terminator__\" line.\n\t\t// @TODO: Should we log a warning on an invalid header line?\n\t\t// What's the typical browser behavior when encountering such a line?\n\t\tif (!line.includes(': ')) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst colonIndex = line.indexOf(': ');\n\t\tconst headerName = line.substring(0, colonIndex).toLowerCase();\n\t\tconst headerValue = line.substring(colonIndex + 2);\n\t\tif (!(headerName in headers)) {\n\t\t\theaders[headerName] = [] as string[];\n\t\t}\n\t\theaders[headerName].push(headerValue);\n\t}\n\treturn {\n\t\theaders,\n\t\thttpStatusCode: headersData.status,\n\t};\n}\n\nasync function streamToText(\n\tstream: ReadableStream<Uint8Array>\n): Promise<string> {\n\tconst reader = (stream as ReadableStream<BufferSource>)\n\t\t.pipeThrough(new TextDecoderStream())\n\t\t.getReader();\n\tconst text: string[] = [];\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) {\n\t\t\treturn text.join('');\n\t\t}\n\t\tif (value) {\n\t\t\ttext.push(value);\n\t\t}\n\t}\n}\n\nasync function streamToBytes(\n\tstream: ReadableStream<Uint8Array>\n): Promise<Uint8Array> {\n\tconst reader = stream.getReader();\n\tconst chunks: Uint8Array[] = [];\n\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) {\n\t\t\tconst totalLength = chunks.reduce(\n\t\t\t\t(acc, chunk) => acc + chunk.byteLength,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst result = new Uint8Array(totalLength);\n\t\t\tlet offset = 0;\n\t\t\tfor (const chunk of chunks) {\n\t\t\t\tresult.set(chunk, offset);\n\t\t\t\toffset += chunk.byteLength;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\tif (value) {\n\t\t\tchunks.push(value);\n\t\t}\n\t}\n}\n\n/**\n * PHP response. Body is an `ArrayBuffer` because it can\n * contain binary data.\n *\n * This type is used in Comlink.transferHandlers.set('PHPResponse', \\{ ... \\})\n * so be sure to update that if you change this type.\n */\nexport class PHPResponse implements PHPResponseData {\n\t/** @inheritDoc */\n\treadonly headers: Record<string, string[]>;\n\n\t/** @inheritDoc */\n\treadonly bytes: Uint8Array;\n\n\t/** @inheritDoc */\n\treadonly errors: string;\n\n\t/** @inheritDoc */\n\treadonly exitCode: number;\n\n\t/** @inheritDoc */\n\treadonly httpStatusCode: number;\n\n\tconstructor(\n\t\thttpStatusCode: number,\n\t\theaders: Record<string, string[]>,\n\t\tbody: Uint8Array,\n\t\terrors = '',\n\t\texitCode = 0\n\t) {\n\t\tthis.httpStatusCode = httpStatusCode;\n\t\tthis.headers = headers;\n\t\tthis.bytes = body;\n\t\tthis.exitCode = exitCode;\n\t\tthis.errors = errors;\n\t}\n\n\tstatic forHttpCode(httpStatusCode: number, text = '') {\n\t\treturn new PHPResponse(\n\t\t\thttpStatusCode,\n\t\t\t{},\n\t\t\tnew TextEncoder().encode(\n\t\t\t\ttext || responseTexts[httpStatusCode] || ''\n\t\t\t)\n\t\t);\n\t}\n\n\tstatic fromRawData(data: PHPResponseData): PHPResponse {\n\t\treturn new PHPResponse(\n\t\t\tdata.httpStatusCode,\n\t\t\tdata.headers,\n\t\t\tdata.bytes,\n\t\t\tdata.errors,\n\t\t\tdata.exitCode\n\t\t);\n\t}\n\n\tstatic async fromStreamedResponse(\n\t\tstreamedResponse: StreamedPHPResponse\n\t): Promise<PHPResponse> {\n\t\tawait streamedResponse.finished;\n\t\treturn new PHPResponse(\n\t\t\tawait streamedResponse.httpStatusCode,\n\t\t\tawait streamedResponse.headers,\n\t\t\tawait streamedResponse.stdoutBytes,\n\t\t\tawait streamedResponse.stderrText,\n\t\t\tawait streamedResponse.exitCode\n\t\t);\n\t}\n\n\t/**\n\t * True if the response is successful (HTTP status code 200-399),\n\t * false otherwise.\n\t */\n\tok(): boolean {\n\t\treturn this.httpStatusCode >= 200 && this.httpStatusCode < 400;\n\t}\n\n\ttoRawData(): PHPResponseData {\n\t\treturn {\n\t\t\theaders: this.headers,\n\t\t\tbytes: this.bytes,\n\t\t\terrors: this.errors,\n\t\t\texitCode: this.exitCode,\n\t\t\thttpStatusCode: this.httpStatusCode,\n\t\t};\n\t}\n\n\t/**\n\t * Response body as JSON.\n\t */\n\tget json() {\n\t\treturn JSON.parse(this.text);\n\t}\n\n\t/**\n\t * Response body as text.\n\t */\n\tget text() {\n\t\treturn new TextDecoder().decode(this.bytes);\n\t}\n}\n","/*\n * Node.js Polyfill for ErrorEvent.\n */\n\nconst kError = Symbol('error');\nconst kMessage = Symbol('message');\n\ninterface ErrorEventOptions {\n\t/* The error that generated this event */\n\terror?: Error;\n\t/* The error message */\n\tmessage?: string;\n}\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent2 extends Event {\n\t[kError]: any;\n\t[kMessage]: any;\n\t/**\n\t * Create a new `ErrorEvent`.\n\t *\n\t * @param type The name of the event\n\t * @param options A dictionary object that allows for setting\n\t * attributes via object members of the same name.\n\t */\n\tconstructor(type: 'error', options: ErrorEventOptions = {}) {\n\t\tsuper(type);\n\n\t\tthis[kError] = options.error === undefined ? null : options.error;\n\t\tthis[kMessage] = options.message === undefined ? '' : options.message;\n\t}\n\n\tget error() {\n\t\treturn this[kError];\n\t}\n\n\tget message() {\n\t\treturn this[kMessage];\n\t}\n}\nObject.defineProperty(ErrorEvent2.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent2.prototype, 'message', { enumerable: true });\n\nexport const ErrorEvent =\n\ttypeof globalThis.ErrorEvent === 'function'\n\t\t? globalThis.ErrorEvent\n\t\t: ErrorEvent2;\n","import { ErrorEvent } from './error-event-polyfill';\nimport { isExitCode } from './is-exit-code';\nimport { logger } from '@php-wasm/logger';\n\ntype Runtime = {\n\twasmExports: Record<string, unknown>;\n\tlastAsyncifyStackSource?: Error;\n};\n\nexport class UnhandledRejectionsTarget extends EventTarget {\n\tlistenersCount = 0;\n\toverride addEventListener(\n\t\ttype: unknown,\n\t\tcallback: unknown,\n\t\toptions?: boolean | AddEventListenerOptions\n\t): void {\n\t\t++this.listenersCount;\n\t\tsuper.addEventListener(\n\t\t\ttype as string,\n\t\t\tcallback as EventListener,\n\t\t\toptions\n\t\t);\n\t}\n\toverride removeEventListener(\n\t\ttype: unknown,\n\t\tcallback: unknown,\n\t\toptions?: boolean | EventListenerOptions\n\t): void {\n\t\t--this.listenersCount;\n\t\tsuper.removeEventListener(\n\t\t\ttype as string,\n\t\t\tcallback as EventListener,\n\t\t\toptions\n\t\t);\n\t}\n\thasListeners() {\n\t\treturn this.listenersCount > 0;\n\t}\n}\n\n/**\n * Creates Asyncify errors listener.\n *\n * Emscripten turns Asyncify errors into unhandled rejections by\n * throwing them outside of the context of the original function call.\n *\n * With this listener, we can catch and rethrow them in a proper context,\n * or at least log them in a more readable way.\n *\n * @param runtime\n */\nexport function improveWASMErrorReporting(runtime: Runtime) {\n\tconst target = new UnhandledRejectionsTarget();\n\tfor (const key in runtime.wasmExports) {\n\t\tif (typeof runtime.wasmExports[key] == 'function') {\n\t\t\tconst original = runtime.wasmExports[key] as any;\n\t\t\truntime.wasmExports[key] = function (...args: any[]) {\n\t\t\t\ttry {\n\t\t\t\t\treturn original(...args);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (!(e instanceof Error)) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (runtime.lastAsyncifyStackSource) {\n\t\t\t\t\t\te.cause = runtime.lastAsyncifyStackSource;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst clearMessage = clarifyErrorMessage(\n\t\t\t\t\t\te,\n\t\t\t\t\t\truntime.lastAsyncifyStackSource?.stack\n\t\t\t\t\t);\n\n\t\t\t\t\tif (target.hasListeners()) {\n\t\t\t\t\t\te.message = clearMessage;\n\t\t\t\t\t\tconst event = new ErrorEvent('error', { error: e });\n\t\t\t\t\t\ttarget.dispatchEvent(event);\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!isExitCode(e) || e.status !== 0) {\n\t\t\t\t\t\tshowCriticalErrorBox(clearMessage);\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\treturn target;\n}\n\nlet functionsMaybeMissingFromAsyncify: string[] = [];\nexport function getFunctionsMaybeMissingFromAsyncify() {\n\treturn functionsMaybeMissingFromAsyncify;\n}\n\nexport function clarifyErrorMessage(\n\tcrypticError: Error,\n\tasyncifyStack?: string\n) {\n\tif (crypticError.message === 'unreachable') {\n\t\tlet betterMessage = UNREACHABLE_ERROR;\n\t\tif (!asyncifyStack) {\n\t\t\tbetterMessage +=\n\t\t\t\t`\\n\\nThis stack trace is lacking. For a better one initialize \\n` +\n\t\t\t\t`the PHP runtime with debug: true, e.g. loadNodeRuntime('8.1', { emscriptenOptions: { debug: true } }).\\n\\n`;\n\t\t}\n\n\t\t// Extract all the PHP functions from the entire error chain.\n\t\tconst uniqueFunctions = new Set<string>(\n\t\t\textractPHPFunctionsFromStack(asyncifyStack || '')\n\t\t);\n\t\tlet lastError = crypticError;\n\t\tdo {\n\t\t\tfor (const fn of extractPHPFunctionsFromStack(\n\t\t\t\tlastError.stack || ''\n\t\t\t)) {\n\t\t\t\tuniqueFunctions.add(fn);\n\t\t\t}\n\t\t\tlastError = lastError.cause as Error;\n\t\t} while (lastError);\n\t\tfunctionsMaybeMissingFromAsyncify = Array.from(uniqueFunctions);\n\n\t\tfor (const fn of uniqueFunctions) {\n\t\t\tbetterMessage += ` * ${fn}\\n`;\n\t\t}\n\n\t\tbetterMessage += `Original error message: ${crypticError.message}\\n`;\n\n\t\treturn betterMessage;\n\t}\n\treturn crypticError.message;\n}\n\nconst UNREACHABLE_ERROR = `\n\"unreachable\" WASM instruction executed.\n\nThe typical reason is a PHP function missing from the ASYNCIFY_ONLY\nlist when building PHP.wasm.\n\nYou will need to file a new issue in the WordPress Playground repository\nand paste this error message there:\n\nhttps://github.com/WordPress/wordpress-playground/issues/new\n\nIf you're a core developer, the typical fix is to:\n\n* Isolate a minimal reproduction of the error\n* Add a reproduction of the error to php-asyncify.spec.ts in the WordPress Playground repository\n* Run 'npm run fix-asyncify'\n* Commit the changes, push to the repo, release updated NPM packages\n\nBelow is a list of all the PHP functions found in the stack trace to\nhelp with the minimal reproduction. If they're all already listed in\nthe Dockerfile, you'll need to trigger this error again with long stack\ntraces enabled. In node.js, you can do it using the --stack-trace-limit=100\nCLI option: \\n\\n`;\n\n// ANSI escape codes for CLI colors and formats\nconst redBg = '\\x1b[41m';\nconst bold = '\\x1b[1m';\nconst reset = '\\x1b[0m';\nconst eol = '\\x1B[K';\n\nlet logged = false;\nexport function showCriticalErrorBox(message: string) {\n\tif (logged) {\n\t\treturn;\n\t}\n\tlogged = true;\n\tif (message?.trim().startsWith('Program terminated with exit')) {\n\t\treturn;\n\t}\n\tlogger.log(`${redBg}\\n${eol}\\n${bold} WASM ERROR${reset}${redBg}`);\n\tfor (const line of message.split('\\n')) {\n\t\tlogger.log(`${eol} ${line} `);\n\t}\n\tlogger.log(`${reset}`);\n}\n\nfunction extractPHPFunctionsFromStack(stack: string) {\n\ttry {\n\t\tconst names = stack\n\t\t\t.split('\\n')\n\t\t\t.slice(1)\n\t\t\t.map((line) => {\n\t\t\t\tconst parts = line.trim().substring('at '.length).split(' ');\n\t\t\t\treturn {\n\t\t\t\t\tfn: parts.length >= 2 ? parts[0] : '<unknown>',\n\t\t\t\t\tisWasm: line.includes('wasm:/'),\n\t\t\t\t};\n\t\t\t})\n\t\t\t.filter(\n\t\t\t\t({ fn, isWasm }) =>\n\t\t\t\t\tisWasm &&\n\t\t\t\t\t!fn.startsWith('dynCall_') &&\n\t\t\t\t\t!fn.startsWith('invoke_')\n\t\t\t)\n\t\t\t.map(({ fn }) => fn);\n\t\treturn Array.from(new Set(names));\n\t} catch {\n\t\treturn [];\n\t}\n}\n","import { logger } from '@php-wasm/logger';\nimport {\n\tSemaphore,\n\tbasename,\n\tcreateSpawnHandler,\n\tjoinPaths,\n} from '@php-wasm/util';\nimport type { Emscripten } from './emscripten-types';\nimport type { ListFilesOptions, RmDirOptions } from './fs-helpers';\nimport { FSHelpers } from './fs-helpers';\nimport { isExitCode } from './is-exit-code';\nimport type { PHPRuntimeId } from './load-php-runtime';\nimport { popLoadedRuntime } from './load-php-runtime';\nimport type { PHPRequestHandler } from './php-request-handler';\nimport { PHPResponse, StreamedPHPResponse } from './php-response';\nimport type {\n\tChildProcess,\n\tMessageListener,\n\tPHPEvent,\n\tPHPEventListener,\n\tPHPRequest,\n\tPHPRequestHeaders,\n\tPHPRunOptions,\n\tSpawnHandler,\n} from './universal-php';\nimport type { UnhandledRejectionsTarget } from './wasm-error-reporting';\nimport {\n\tgetFunctionsMaybeMissingFromAsyncify,\n\timproveWASMErrorReporting,\n} from './wasm-error-reporting';\n\nconst STRING = 'string';\nconst NUMBER = 'number';\n\nexport const __private__dont__use = Symbol('__private__dont__use');\n\ntype ErrorSource = 'request' | 'php-wasm';\nexport class PHPExecutionFailureError extends Error {\n\tresponse: PHPResponse;\n\tsource: ErrorSource;\n\n\tconstructor(message: string, response: PHPResponse, source: ErrorSource) {\n\t\tsuper(message);\n\t\tthis.response = response;\n\t\tthis.source = source;\n\t}\n}\n\nexport type UnmountFunction = (() => Promise<any>) | (() => any);\nexport type MountHandler = (\n\tphp: PHP,\n\tFS: Emscripten.RootFS,\n\tvfsMountPoint: string\n) => UnmountFunction | Promise<UnmountFunction>;\n\nexport const PHP_INI_PATH = '/internal/shared/php.ini';\nconst AUTO_PREPEND_SCRIPT = '/internal/shared/auto_prepend_file.php';\n\nexport const USE_OPCACHE = true;\nconst OPCACHE_FILE_FOLDER = '/internal/shared/opcache';\n\ntype MountObject = {\n\tmountHandler: MountHandler;\n\tunmount: () => Promise<any>;\n};\n\n/**\n * An environment-agnostic wrapper around the Emscripten PHP runtime\n * that universals the super low-level API and provides a more convenient\n * higher-level API.\n *\n * It exposes a minimal set of methods to run PHP scripts and to\n * interact with the PHP filesystem.\n */\nexport class PHP implements Disposable {\n\tprotected [__private__dont__use]: any;\n\t#sapiName?: string;\n\t#phpWasmInitCalled = false;\n\t#wasmErrorsTarget: UnhandledRejectionsTarget | null = null;\n\t#eventListeners: Map<string, Set<PHPEventListener>> = new Map([\n\t\t// Listen to all events\n\t\t['*', new Set()],\n\t]);\n\t#messageListeners: MessageListener[] = [];\n\t#mounts: Record<string, MountObject> = {};\n\t#rotationOptions: {\n\t\tenabled: boolean;\n\t\trecreateRuntime: () => Promise<number> | number;\n\t\tneedsRotating: boolean;\n\t\tmaxRequests: number;\n\t\trequestsMade: number;\n\t} = {\n\t\tenabled: false,\n\t\trecreateRuntime: () => 0,\n\t\tneedsRotating: false,\n\t\tmaxRequests: 400,\n\t\trequestsMade: 0,\n\t};\n\n\trequestHandler?: PHPRequestHandler;\n\n\t/**\n\t * An exclusive lock that prevent multiple requests from running at\n\t * the same time.\n\t */\n\tsemaphore: Semaphore;\n\n\t/**\n\t * Initializes a PHP runtime.\n\t *\n\t * @internal\n\t * @param PHPRuntime - Optional. PHP Runtime ID as initialized by loadPHPRuntime.\n\t * @param requestHandlerOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.\n\t */\n\tconstructor(PHPRuntimeId?: PHPRuntimeId) {\n\t\tthis.semaphore = new Semaphore({ concurrency: 1 });\n\t\tif (PHPRuntimeId !== undefined) {\n\t\t\tthis.initializeRuntime(PHPRuntimeId);\n\t\t}\n\t\t/**\n\t\t * Listen to PHP runtime crashes.\n\t\t *\n\t\t * Registering an actual event listener helps with testing. The\n\t\t * test cases can dispatch synthetic error events and confirm the\n\t\t * PHP runtime is properly rotated.\n\t\t */\n\t\tthis.addEventListener('request.error', (event: any) => {\n\t\t\tif (event.source === 'php-wasm') {\n\t\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t * Adds an event listener for a PHP event.\n\t * @param eventType - The type of event to listen for.\n\t * @param listener - The listener function to be called when the event is triggered.\n\t */\n\taddEventListener(\n\t\teventType: PHPEvent['type'] | '*',\n\t\tlistener: PHPEventListener\n\t) {\n\t\tif (!this.#eventListeners.has(eventType)) {\n\t\t\tthis.#eventListeners.set(eventType, new Set());\n\t\t}\n\t\tthis.#eventListeners.get(eventType)!.add(listener);\n\t}\n\n\t/**\n\t * Removes an event listener for a PHP event.\n\t * @param eventType - The type of event to remove the listener from.\n\t * @param listener - The listener function to be removed.\n\t */\n\tremoveEventListener(\n\t\teventType: PHPEvent['type'] | '*',\n\t\tlistener: PHPEventListener\n\t) {\n\t\tthis.#eventListeners.get(eventType)?.delete(listener);\n\t}\n\n\tdispatchEvent<Event extends PHPEvent>(event: Event) {\n\t\tconst listeners = [\n\t\t\t...(this.#eventListeners.get(event.type) || []),\n\t\t\t...(this.#eventListeners.get('*') || []),\n\t\t];\n\t\tif (!listeners) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const listener of listeners) {\n\t\t\tlistener(event);\n\t\t}\n\t}\n\n\t/**\n\t * Listens to message sent by the PHP code.\n\t *\n\t * To dispatch messages, call:\n\t *\n\t * post_message_to_js(string $data)\n\t *\n\t * Arguments:\n\t * $data (string) – Data to pass to JavaScript.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const php = await PHP.load('8.0');\n\t *\n\t * php.onMessage(\n\t * // The data is always passed as a string\n\t * function (data: string) {\n\t * // Let's decode and log the data:\n\t * console.log(JSON.parse(data));\n\t * }\n\t * );\n\t *\n\t * // Now that we have a listener in place, let's\n\t * // dispatch a message:\n\t * await php.run({\n\t * code: `<?php\n\t * post_message_to_js(\n\t * json_encode([\n\t * 'post_id' => '15',\n\t * 'post_title' => 'This is a blog post!'\n\t * ])\n\t * ));\n\t * `,\n\t * });\n\t * ```\n\t *\n\t * @param listener Callback function to handle the message.\n\t */\n\tonMessage(listener: MessageListener) {\n\t\tthis.#messageListeners.push(listener);\n\t\treturn async () => {\n\t\t\tthis.#messageListeners = this.#messageListeners.filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t};\n\t}\n\n\tasync setSpawnHandler(handler: SpawnHandler | string) {\n\t\tif (typeof handler === 'string') {\n\t\t\t// This workaround is needed because the\n\t\t\t// Comlink messaging library used by Playground\n\t\t\t// has a hard time serializing a composite\n\t\t\t// handler object.\n\t\t\t// @TODO: Don't eval text-based functions here. Instead\n\t\t\t// use a MessagePort to communicate with the\n\t\t\t//\t\t parent context.\n\t\t\t// Perhaps this library would be useful:\n\t\t\t// https://github.com/WebReflection/coincident/\n\t\t\thandler = createSpawnHandler(eval(handler));\n\t\t}\n\t\tthis[__private__dont__use].spawnProcess = handler;\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tget absoluteUrl() {\n\t\treturn this.requestHandler!.absoluteUrl;\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tget documentRoot() {\n\t\treturn this.requestHandler!.documentRoot;\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tpathToInternalUrl(path: string): string {\n\t\treturn this.requestHandler!.pathToInternalUrl(path);\n\t}\n\n\t/** @deprecated Use PHPRequestHandler instead. */\n\tinternalUrlToPath(internalUrl: string): string {\n\t\treturn this.requestHandler!.internalUrlToPath(internalUrl);\n\t}\n\n\tinitializeRuntime(runtimeId: PHPRuntimeId) {\n\t\tif (this[__private__dont__use]) {\n\t\t\tthrow new Error('PHP runtime already initialized.');\n\t\t}\n\t\tconst runtime = popLoadedRuntime(runtimeId);\n\t\tif (!runtime) {\n\t\t\tthrow new Error('Invalid PHP runtime id.');\n\t\t}\n\t\tthis[__private__dont__use] = runtime;\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_phpini_path',\n\t\t\tnull,\n\t\t\t['string'],\n\t\t\t[PHP_INI_PATH]\n\t\t);\n\n\t\tif (!this.fileExists(PHP_INI_PATH)) {\n\t\t\tconst opcacheConfig = USE_OPCACHE\n\t\t\t\t? [\n\t\t\t\t\t\t// OPCache\n\t\t\t\t\t\t'opcache.enable = 1',\n\t\t\t\t\t\t'opcache.enable_cli = 1',\n\t\t\t\t\t\t'opcache.jit = 0',\n\t\t\t\t\t\t'opcache.interned_strings_buffer = 8',\n\t\t\t\t\t\t'opcache.max_accelerated_files = 1000',\n\t\t\t\t\t\t'opcache.memory_consumption = 64',\n\t\t\t\t\t\t'opcache.max_wasted_percentage = 5',\n\t\t\t\t\t\t'opcache.file_cache = ' + OPCACHE_FILE_FOLDER,\n\t\t\t\t\t\t// Always enable the file cache.\n\t\t\t\t\t\t'opcache.file_cache_only = 1',\n\t\t\t\t\t\t'opcache.file_cache_consistency_checks = 1',\n\t\t\t\t\t]\n\t\t\t\t: [];\n\n\t\t\t/*if (\n\t\t\t\tUSE_OPCACHE &&\n\t\t\t\t!(\n\t\t\t\t\truntime.phpVersion.major === 8 &&\n\t\t\t\t\truntime.phpVersion.minor === 4\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\t// Old versions of PHP are RAM hungry. By using the file cache, we can reduce\n\t\t\t\t// the RAM usage during the first caching.\n\t\t\t\topcacheConfig.push(\n\t\t\t\t\t'opcache.file_cache_only = 1',\n\t\t\t\t\t'opcache.file_cache_consistency_checks = 1'\n\t\t\t\t);\n\t\t\t}*/\n\n\t\t\tif (!this.fileExists(OPCACHE_FILE_FOLDER)) {\n\t\t\t\tthis.mkdir(OPCACHE_FILE_FOLDER);\n\t\t\t}\n\n\t\t\tthis.writeFile(\n\t\t\t\tPHP_INI_PATH,\n\t\t\t\t[\n\t\t\t\t\t'auto_prepend_file=' + AUTO_PREPEND_SCRIPT,\n\t\t\t\t\t'memory_limit=256M',\n\t\t\t\t\t'ignore_repeated_errors = 1',\n\t\t\t\t\t'error_reporting = E_ALL',\n\t\t\t\t\t'display_errors = 1',\n\t\t\t\t\t'html_errors = 1',\n\t\t\t\t\t'display_startup_errors = On',\n\t\t\t\t\t'log_errors = 1',\n\t\t\t\t\t'always_populate_raw_post_data = -1',\n\t\t\t\t\t'upload_max_filesize = 2000M',\n\t\t\t\t\t'post_max_size = 2000M',\n\t\t\t\t\t'allow_url_fopen = On',\n\t\t\t\t\t'allow_url_include = Off',\n\t\t\t\t\t'session.save_path = /home/web_user',\n\t\t\t\t\t'implicit_flush = 1',\n\t\t\t\t\t'output_buffering = 0',\n\t\t\t\t\t'max_execution_time = 0',\n\t\t\t\t\t'max_input_time = -1',\n\t\t\t\t\t...opcacheConfig,\n\t\t\t\t].join('\\n')\n\t\t\t);\n\t\t}\n\t\tif (!this.fileExists(AUTO_PREPEND_SCRIPT)) {\n\t\t\tthis.writeFile(\n\t\t\t\tAUTO_PREPEND_SCRIPT,\n\t\t\t\t`<?php\n\t\t\t\t// Define constants set via defineConstant() calls\n\t\t\t\tif(file_exists('/internal/shared/consts.json')) {\n\t\t\t\t\t$consts = json_decode(file_get_contents('/internal/shared/consts.json'), true);\n\t\t\t\t\tforeach ($consts as $const => $value) {\n\t\t\t\t\t\tif (!defined($const) && is_scalar($value)) {\n\t\t\t\t\t\t\tdefine($const, $value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Preload all the files from /internal/shared/preload\n\t\t\t\tforeach (glob('/internal/shared/preload/*.php') as $file) {\n\t\t\t\t\trequire_once $file;\n\t\t\t\t}\n\t\t\t\t`\n\t\t\t);\n\t\t}\n\n\t\truntime['onMessage'] = async (\n\t\t\tdata: string\n\t\t): Promise<string | Uint8Array> => {\n\t\t\tfor (const listener of this.#messageListeners) {\n\t\t\t\tconst returnData = await listener(data);\n\n\t\t\t\tif (returnData) {\n\t\t\t\t\treturn returnData;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn '';\n\t\t};\n\n\t\tthis.#wasmErrorsTarget = improveWASMErrorReporting(runtime);\n\t\tthis.dispatchEvent({\n\t\t\ttype: 'runtime.initialized',\n\t\t});\n\t}\n\n\t/** @inheritDoc */\n\tasync setSapiName(newName: string) {\n\t\tconst result = this[__private__dont__use].ccall(\n\t\t\t'wasm_set_sapi_name',\n\t\t\tNUMBER,\n\t\t\t[STRING],\n\t\t\t[newName]\n\t\t);\n\t\tif (result !== 0) {\n\t\t\tthrow new Error(\n\t\t\t\t'Could not set SAPI name. This can only be done before the PHP WASM module is initialized.' +\n\t\t\t\t\t'Did you already dispatch any requests?'\n\t\t\t);\n\t\t}\n\t\tthis.#sapiName = newName;\n\t}\n\n\t/**\n\t * Changes the current working directory in the PHP filesystem.\n\t * This is the directory that will be used as the base for relative paths.\n\t * For example, if the current working directory is `/root/php`, and the\n\t * path is `data`, the absolute path will be `/root/php/data`.\n\t *\n\t * @param path - The new working directory.\n\t */\n\tchdir(path: string) {\n\t\tthis[__private__dont__use].FS.chdir(path);\n\t}\n\n\t/**\n\t * Gets the current working directory in the PHP filesystem.\n\t *\n\t * @returns The current working directory.\n\t */\n\tcwd() {\n\t\treturn this[__private__dont__use].FS.cwd();\n\t}\n\n\t/**\n\t * Changes the permissions of a file or directory.\n\t * @param path - The path to the file or directory.\n\t * @param mode - The new permissions.\n\t */\n\tchmod(path: string, mode: number) {\n\t\tthis[__private__dont__use].FS.chmod(path, mode);\n\t}\n\n\t/**\n\t * Do not use. Use new PHPRequestHandler() instead.\n\t * @deprecated\n\t */\n\tasync request(request: PHPRequest): Promise<PHPResponse> {\n\t\tlogger.warn(\n\t\t\t'PHP.request() is deprecated. Please use new PHPRequestHandler() instead.'\n\t\t);\n\t\tif (!this.requestHandler) {\n\t\t\tthrow new Error('No request handler available.');\n\t\t}\n\t\treturn this.requestHandler.request(request);\n\t}\n\n\t/**\n\t * Runs PHP code.\n\t *\n\t * This low-level method directly interacts with the WebAssembly\n\t * PHP interpreter.\n\t *\n\t * Every time you call run(), it prepares the PHP\n\t * environment and:\n\t *\n\t * * Resets the internal PHP state\n\t * * Populates superglobals ($_SERVER, $_GET, etc.)\n\t * * Handles file uploads\n\t * * Populates input streams (stdin, argv, etc.)\n\t * * Sets the current working directory\n\t *\n\t * You can use run() in two primary modes:\n\t *\n\t * ### Code snippet mode\n\t *\n\t * In this mode, you pass a string containing PHP code to run.\n\t *\n\t * ```ts\n\t * const result = await php.run({\n\t * \tcode: `<?php echo \"Hello world!\";`\n\t * });\n\t * // result.text === \"Hello world!\"\n\t * ```\n\t *\n\t * In this mode, information like __DIR__ or __FILE__ isn't very\n\t * useful because the code is not associated with any file.\n\t *\n\t * Under the hood, the PHP snippet is passed to the `zend_eval_string`\n\t * C function.\n\t *\n\t * ### File mode\n\t *\n\t * In the file mode, you pass a scriptPath and PHP executes a file\n\t * found at a that path:\n\t *\n\t * ```ts\n\t * php.writeFile(\n\t * \t\"/www/index.php\",\n\t * \t`<?php echo \"Hello world!\";\"`\n\t * );\n\t * const result = await php.run({\n\t * \tscriptPath: \"/www/index.php\"\n\t * });\n\t * // result.text === \"Hello world!\"\n\t * ```\n\t *\n\t * In this mode, you can rely on path-related information like __DIR__\n\t * or __FILE__.\n\t *\n\t * Under the hood, the PHP file is executed with the `php_execute_script`\n\t * C function.\n\t *\n\t * The `run()` method cannot be used in conjunction with `cli()`.\n\t *\n\t * @example\n\t * ```js\n\t * const result = await php.run({\n\t * \tcode: `<?php\n\t * \t\t$fp = fopen('php://stderr', 'w');\n\t * \t\tfwrite($fp, \"Hello, world!\");\n\t * \t`\n\t * });\n\t * // result.errors === \"Hello, world!\"\n\t * ```\n\t *\n\t * @deprecated Use stream() instead.\n\t * @param request - PHP runtime options.\n\t */\n\tasync run(request: PHPRunOptions): Promise<PHPResponse> {\n\t\tconst streamedResponse = await this.runStream(request);\n\t\tconst syncResponse =\n\t\t\tawait PHPResponse.fromStreamedResponse(streamedResponse);\n\n\t\tif (syncResponse.exitCode !== 0) {\n\t\t\t// Legacy run() behavior: throw if PHP exited with a non-zero exit code.\n\t\t\t// It could be a WASM crash, but it could be a PHP userland error such\n\t\t\t// as \"Fatal error: Uncaught Error: Call to undefined function no_such_function()\".\n\t\t\t//\n\t\t\t// runStream() does not throw just because an exitCode is non-zero.\n\t\t\tthrow new PHPExecutionFailureError(\n\t\t\t\t`PHP.run() failed with exit code ${syncResponse.exitCode}. \\n\\n=== Stdout ===\\n ${syncResponse.text}\\n\\n=== Stderr ===\\n ${syncResponse.errors}`,\n\t\t\t\tsyncResponse,\n\t\t\t\t'request'\n\t\t\t) as PHPExecutionFailureError;\n\t\t}\n\n\t\treturn syncResponse;\n\t}\n\t/**\n\t * Runs PHP code and returns a StreamedPHPResponse object that can be used to\n\t * process the output incrementally.\n\t *\n\t * This low-level method directly interacts with the WebAssembly\n\t * PHP interpreter and provides streaming capabilities for processing\n\t * PHP output as it becomes available.\n\t *\n\t * Every time you call stream(), it prepares the PHP\n\t * environment and:\n\t *\n\t * * Resets the internal PHP state\n\t * * Populates superglobals ($_SERVER, $_GET, etc.)\n\t * * Handles file uploads\n\t * * Populates input streams (stdin, argv, etc.)\n\t * * Sets the current working directory\n\t *\n\t * You can use stream() in two primary modes:\n\t *\n\t * ### Code snippet mode\n\t *\n\t * In this mode, you pass a string containing PHP code to run.\n\t *\n\t * ```ts\n\t * const streamedResponse = await php.stream({\n\t * \tcode: `<?php echo \"Hello world!\";`\n\t * });\n\t * // Process output incrementally\n\t * for await (const chunk of streamedResponse.text) {\n\t * \tconsole.log(chunk);\n\t * }\n\t * ```\n\t *\n\t * In this mode, information like __DIR__ or __FILE__ isn't very\n\t * useful because the code is not associated with any file.\n\t *\n\t * Under the hood, the PHP snippet is passed to the `zend_eval_string`\n\t * C function.\n\t *\n\t * ### File mode\n\t *\n\t * In the file mode, you pass a scriptPath and PHP executes a file\n\t * found at that path:\n\t *\n\t * ```ts\n\t * php.writeFile(\n\t * \t\"/www/index.php\",\n\t * \t`<?php echo \"Hello world!\";\"`\n\t * );\n\t * const streamedResponse = await php.stream({\n\t * \tscriptPath: \"/www/index.php\"\n\t * });\n\t * // Process output incrementally\n\t * for await (const chunk of streamedResponse.text) {\n\t * \tconsole.log(chunk);\n\t * }\n\t * ```\n\t *\n\t * In this mode, you can rely on path-related information like __DIR__\n\t * or __FILE__.\n\t *\n\t * Under the hood, the PHP file is executed with the `php_execute_script`\n\t * C function.\n\t *\n\t * The `stream()` method cannot be used in conjunction with `cli()`.\n\t *\n\t * @example\n\t * ```js\n\t * const streamedResponse = await php.stream({\n\t * \tcode: `<?php\n\t * \t\tfor ($i = 0; $i < 5; $i++) {\n\t * \t\t\techo \"Line $i\\n\";\n\t * \t\t\tflush();\n\t * \t\t}\n\t * \t`\n\t * });\n\t *\n\t * // Process output as it becomes available\n\t * for await (const chunk of streamedResponse.text) {\n\t * \tconsole.log('Received:', chunk);\n\t * }\n\t *\n\t * // Get the final exit code\n\t * const exitCode = await streamedResponse.exitCode;\n\t * console.log('Exit code:', exitCode);\n\t * ```\n\t *\n\t * @see run() – a synchronous version of this method.\n\t * @param request - PHP runtime options.\n\t * @returns A StreamedPHPResponse object.\n\t */\n\tasync runStream(request: PHPRunOptions): Promise<StreamedPHPResponse> {\n\t\t/*\n\t\t * Prevent multiple requests from running at the same time.\n\t\t * For example, if a request is made to a PHP file that\n\t\t * requests another PHP file, the second request may\n\t\t * be dispatched before the first one is finished.\n\t\t */\n\t\tconst release = await this.semaphore.acquire();\n\t\tlet heapBodyPointer: number | undefined;\n\t\tconst streamedResponsePromise = this.#executeWithErrorHandling(\n\t\t\tasync () => {\n\t\t\t\tif (!this.#phpWasmInitCalled) {\n\t\t\t\t\tawait this[__private__dont__use].ccall(\n\t\t\t\t\t\t'php_wasm_init',\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t[],\n\t\t\t\t\t\t[],\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisAsync: true,\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tthis.#phpWasmInitCalled = true;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\trequest.scriptPath &&\n\t\t\t\t\t!this.fileExists(request.scriptPath)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The script path \"${request.scriptPath}\" does not exist.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.#setRelativeRequestUri(request.relativeUri || '');\n\t\t\t\tthis.#setRequestMethod(request.method || 'GET');\n\t\t\t\tconst requestHeaders = normalizeHeaders(request.headers || {});\n\t\t\t\tconst host = requestHeaders['host'] || 'example.com:443';\n\n\t\t\t\tconst port = this.#inferPortFromHostAndProtocol(\n\t\t\t\t\thost,\n\t\t\t\t\trequest.protocol || 'http'\n\t\t\t\t);\n\t\t\t\tthis.#setRequestHost(host);\n\t\t\t\tthis.#setRequestPort(port);\n\t\t\t\tthis.#setRequestHeaders(requestHeaders);\n\t\t\t\tif (request.body) {\n\t\t\t\t\theapBodyPointer = this.#setRequestBody(request.body);\n\t\t\t\t}\n\t\t\t\tif (typeof request.code === 'string') {\n\t\t\t\t\tthis.writeFile('/internal/eval.php', request.code);\n\t\t\t\t\tthis.#setScriptPath('/internal/eval.php');\n\t\t\t\t} else if (typeof request.scriptPath === 'string') {\n\t\t\t\t\tthis.#setScriptPath(request.scriptPath || '');\n\t\t\t\t} else {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'The request object must have either a `code` or a ' +\n\t\t\t\t\t\t\t'`scriptPath` property.'\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst $_SERVER = this.#prepareServerEntries(\n\t\t\t\t\trequest.$_SERVER,\n\t\t\t\t\trequestHeaders,\n\t\t\t\t\tport\n\t\t\t\t);\n\n\t\t\t\tfor (const key in $_SERVER) {\n\t\t\t\t\tthis.#setServerGlobalEntry(key, $_SERVER[key]);\n\t\t\t\t}\n\n\t\t\t\tconst env = request.env || {};\n\t\t\t\tfor (const key in env) {\n\t\t\t\t\tthis.#setEnv(key, env[key]);\n\t\t\t\t}\n\n\t\t\t\treturn await this[__private__dont__use].ccall(\n\t\t\t\t\t'wasm_sapi_handle_request',\n\t\t\t\t\tNUMBER,\n\t\t\t\t\t[],\n\t\t\t\t\t[],\n\t\t\t\t\t{ async: true }\n\t\t\t\t);\n\t\t\t}\n\t\t);\n\n\t\tconst cleanup = () => {\n\t\t\tif (heapBodyPointer) {\n\t\t\t\ttry {\n\t\t\t\t\tthis[__private__dont__use].free(heapBodyPointer);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlogger.error(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Release the \"request in progress\" semaphore.\n\t\t\trelease();\n\n\t\t\t/**\n\t\t\t * Notify the filesystem journal (and any other listeners) that the request has ended.\n\t\t\t */\n\t\t\tthis.dispatchEvent({\n\t\t\t\ttype: 'request.end',\n\t\t\t});\n\t\t};\n\n\t\t// Free up resources once the request is fully handled.\n\t\treturn streamedResponsePromise.then(\n\t\t\t(streamedResponse) => {\n\t\t\t\tstreamedResponse.finished.finally(cleanup);\n\t\t\t\treturn streamedResponse;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\ttry {\n\t\t\t\t\tcleanup();\n\t\t\t\t} catch {\n\t\t\t\t\t// ... do nothing, just rethrow the original error in the finally section belos ...\n\t\t\t\t} finally {\n\t\t\t\t\t// eslint-disable-next-line no-unsafe-finally\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Prepares the $_SERVER entries for the PHP runtime.\n\t *\n\t * @param defaults Default entries to include in $_SERVER.\n\t * @param headers HTTP headers to include in $_SERVER (as HTTP_ prefixed entries).\n\t * @param port HTTP port, used to determine infer $_SERVER['HTTPS'] value if none\n\t * was provided.\n\t * @returns Computed $_SERVER entries.\n\t */\n\t#prepareServerEntries(\n\t\tdefaults: Record<string, string> | undefined,\n\t\theaders: PHPRequestHeaders,\n\t\tport: number\n\t): Record<string, string> {\n\t\tconst $_SERVER = {\n\t\t\t...(defaults || {}),\n\t\t};\n\t\t$_SERVER['HTTPS'] = $_SERVER['HTTPS'] || port === 443 ? 'on' : 'off';\n\t\tfor (const name in headers) {\n\t\t\tlet HTTP_prefix = 'HTTP_';\n\t\t\t/**\n\t\t\t * Some headers are special and don't have the HTTP_ prefix.\n\t\t\t */\n\t\t\tif (\n\t\t\t\t['content-type', 'content-length'].includes(name.toLowerCase())\n\t\t\t) {\n\t\t\t\tHTTP_prefix = '';\n\t\t\t}\n\t\t\t$_SERVER[`${HTTP_prefix}${name.toUpperCase().replace(/-/g, '_')}`] =\n\t\t\t\theaders[name];\n\t\t}\n\t\treturn $_SERVER;\n\t}\n\n\t#setRelativeRequestUri(uri: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_uri',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[uri]\n\t\t);\n\t\tlet queryString = '';\n\t\tif (uri.includes('?')) {\n\t\t\tqueryString = uri.substring(uri.indexOf('?') + 1);\n\t\t}\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_query_string',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[queryString]\n\t\t);\n\t}\n\n\t#setRequestHost(host: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_host',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[host]\n\t\t);\n\t}\n\n\t#setRequestPort(port: number) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_port',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[port]\n\t\t);\n\t}\n\n\t#inferPortFromHostAndProtocol(host: string, protocol: string) {\n\t\tlet port;\n\t\ttry {\n\t\t\tport = parseInt(new URL(host).port, 10);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\n\t\tif (!port || isNaN(port) || port === 80) {\n\t\t\tport = protocol === 'https' ? 443 : 80;\n\t\t}\n\t\treturn port;\n\t}\n\n\t#setRequestMethod(method: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_method',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[method]\n\t\t);\n\t}\n\n\t#setRequestHeaders(headers: PHPRequestHeaders) {\n\t\tif (headers['cookie']) {\n\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t'wasm_set_cookies',\n\t\t\t\tnull,\n\t\t\t\t[STRING],\n\t\t\t\t[headers['cookie']]\n\t\t\t);\n\t\t}\n\t\tif (headers['content-type']) {\n\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t'wasm_set_content_type',\n\t\t\t\tnull,\n\t\t\t\t[STRING],\n\t\t\t\t[headers['content-type']]\n\t\t\t);\n\t\t}\n\t\tif (headers['content-length']) {\n\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t'wasm_set_content_length',\n\t\t\t\tnull,\n\t\t\t\t[NUMBER],\n\t\t\t\t[parseInt(headers['content-length'], 10)]\n\t\t\t);\n\t\t}\n\t}\n\n\t#setRequestBody(body: string | Uint8Array) {\n\t\tlet size, contentLength;\n\t\tif (typeof body === 'string') {\n\t\t\tlogger.warn(\n\t\t\t\t'Passing a string as the request body is deprecated. Please use a Uint8Array instead. See ' +\n\t\t\t\t\t'https://github.com/WordPress/wordpress-playground/issues/997 for more details'\n\t\t\t);\n\t\t\tcontentLength = this[__private__dont__use].lengthBytesUTF8(body);\n\t\t\tsize = contentLength + 1;\n\t\t} else {\n\t\t\tcontentLength = body.byteLength;\n\t\t\tsize = body.byteLength;\n\t\t}\n\n\t\tconst heapBodyPointer = this[__private__dont__use].malloc(size);\n\t\tif (!heapBodyPointer) {\n\t\t\tthrow new Error('Could not allocate memory for the request body.');\n\t\t}\n\n\t\t// Write the string to the WASM memory\n\t\tif (typeof body === 'string') {\n\t\t\tthis[__private__dont__use].stringToUTF8(\n\t\t\t\tbody,\n\t\t\t\theapBodyPointer,\n\t\t\t\tsize + 1\n\t\t\t);\n\t\t} else {\n\t\t\tthis[__private__dont__use].HEAPU8.set(body, heapBodyPointer);\n\t\t}\n\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_request_body',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[heapBodyPointer]\n\t\t);\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_content_length',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[contentLength]\n\t\t);\n\t\treturn heapBodyPointer;\n\t}\n\n\t#setScriptPath(path: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_path_translated',\n\t\t\tnull,\n\t\t\t[STRING],\n\t\t\t[path]\n\t\t);\n\t}\n\n\t#setServerGlobalEntry(key: string, value: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_add_SERVER_entry',\n\t\t\tnull,\n\t\t\t[STRING, STRING],\n\t\t\t[key, value]\n\t\t);\n\t}\n\n\t#setEnv(name: string, value: string) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_add_ENV_entry',\n\t\t\tnull,\n\t\t\t[STRING, STRING],\n\t\t\t[name, value]\n\t\t);\n\t}\n\n\t/**\n\t * Defines a constant in the PHP runtime.\n\t * @param key - The name of the constant.\n\t * @param value - The value of the constant.\n\t */\n\tdefineConstant(key: string, value: string | boolean | number | null) {\n\t\tlet consts = {};\n\t\ttry {\n\t\t\tconsts = JSON.parse(\n\t\t\t\tthis.fileExists('/internal/shared/consts.json')\n\t\t\t\t\t? this.readFileAsText('/internal/shared/consts.json') ||\n\t\t\t\t\t\t\t'{}'\n\t\t\t\t\t: '{}'\n\t\t\t);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t\tthis.writeFile(\n\t\t\t'/internal/shared/consts.json',\n\t\t\tJSON.stringify({\n\t\t\t\t...consts,\n\t\t\t\t[key]: value,\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Executes a PHP runtime function with proper error handling and streaming setup.\n\t * Sets up streaming infrastructure and returns a StreamedPHPResponse.\n\t *\n\t * @param executionFn - Function that returns the exit code or a promise of exit code\n\t * @returns Promise that resolves to a StreamedPHPResponse\n\t */\n\tasync #executeWithErrorHandling(\n\t\texecutionFn: () => any\n\t): Promise<StreamedPHPResponse> {\n\t\tif (\n\t\t\tthis.#rotationOptions.enabled &&\n\t\t\tthis.#rotationOptions.needsRotating\n\t\t) {\n\t\t\tawait this.rotateRuntime();\n\t\t}\n\t\t++this.#rotationOptions.requestsMade;\n\t\tif (\n\t\t\tthis.#rotationOptions.requestsMade >=\n\t\t\tthis.#rotationOptions.maxRequests\n\t\t) {\n\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t}\n\n\t\tconst emscriptenModule = this[__private__dont__use];\n\n\t\tconst headers = await createInvertedReadableStream<Uint8Array>();\n\t\temscriptenModule.onHeaders = (chunk: Uint8Array) => {\n\t\t\tif (streamsClosed || headersClosed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// slice() chunk to clone the data and preserve it for the reader later on.\n\t\t\t// We need that because the ArrayBuffer underlying `chunk` may change\n\t\t\t// after this callback return. Without cloning, the reader would read\n\t\t\t// whatever bytes are available in the ArrayBuffer at the time of the read.\n\t\t\theaders.controller.enqueue(chunk.slice());\n\t\t};\n\t\tlet headersClosed = false;\n\t\tconst closeHeadersStream = () => {\n\t\t\tif (!headersClosed) {\n\t\t\t\theadersClosed = true;\n\t\t\t\theaders.controller.close();\n\t\t\t}\n\t\t};\n\n\t\tconst stdout = await createInvertedReadableStream<Uint8Array>();\n\t\temscriptenModule.onStdout = (chunk: Uint8Array) => {\n\t\t\tcloseHeadersStream();\n\t\t\tif (streamsClosed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstdout.controller.enqueue(chunk.slice());\n\t\t};\n\n\t\tconst stderr = await createInvertedReadableStream<Uint8Array>();\n\t\temscriptenModule.onStderr = (chunk: Uint8Array) => {\n\t\t\tif (streamsClosed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstderr.controller.enqueue(chunk.slice());\n\t\t};\n\n\t\tlet streamsClosed = false;\n\n\t\tlet errorListener: any;\n\n\t\tconst runExecutionFunction = async () => {\n\t\t\ttry {\n\t\t\t\t/*\n\t\t\t\t * Emscripten throws WASM failures outside of the promise chain so we need\n\t\t\t\t * to listen for them here and rethrow in the correct context. Otherwise we\n\t\t\t\t * get crashes and unhandled promise rejections without any useful error\n\t\t\t\t * messages or meaningful stack traces.\n\t\t\t\t */\n\t\t\t\tconst exitCode = await Promise.race([\n\t\t\t\t\texecutionFn(),\n\t\t\t\t\tnew Promise((_, reject) => {\n\t\t\t\t\t\terrorListener = (e: ErrorEvent) => {\n\t\t\t\t\t\t\tif (!isExitCode(e.error)) {\n\t\t\t\t\t\t\t\treject(e.error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tthis.#wasmErrorsTarget?.addEventListener(\n\t\t\t\t\t\t\t'error',\n\t\t\t\t\t\t\terrorListener,\n\t\t\t\t\t\t\t{ once: true }\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t\treturn exitCode;\n\t\t\t} catch (e) {\n\t\t\t\t/**\n\t\t\t\t * Emscripten sometimes communicates program exit as an error. Let's\n\t\t\t\t * turn exit code errors into integers again.\n\t\t\t\t */\n\t\t\t\tif (isExitCode(e)) {\n\t\t\t\t\treturn e.status;\n\t\t\t\t}\n\n\t\t\t\t// Non-exit-code errors indicate a WASM runtime crash. Let's clean up and throw.\n\t\t\t\tstdout.controller.error(e);\n\t\t\t\tstderr.controller.error(e);\n\t\t\t\theaders.controller.error(e);\n\t\t\t\tstreamsClosed = true;\n\n\t\t\t\t/**\n\t\t\t\t * A non-exit-code error means an irrecoverable crash. Let's make\n\t\t\t\t * it very clear to the consumers of this API – every method\n\t\t\t\t * call on this PHP instance will throw an error from now on.\n\t\t\t\t */\n\t\t\t\tfor (const name in this) {\n\t\t\t\t\tif (typeof this[name] === 'function') {\n\t\t\t\t\t\t(this as any)[name] = () => {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`PHP runtime has crashed – see the earlier error for details.`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t(this as any).functionsMaybeMissingFromAsyncify =\n\t\t\t\t\tgetFunctionsMaybeMissingFromAsyncify();\n\n\t\t\t\tthrow e;\n\t\t\t} finally {\n\t\t\t\tif (!streamsClosed) {\n\t\t\t\t\tstdout.controller.close();\n\t\t\t\t\tstderr.controller.close();\n\t\t\t\t\tcloseHeadersStream();\n\t\t\t\t\tstreamsClosed = true;\n\t\t\t\t}\n\t\t\t\tthis.#wasmErrorsTarget?.removeEventListener(\n\t\t\t\t\t'error',\n\t\t\t\t\terrorListener\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\t/**\n\t\t * Dispatch a request.error event for any global crash handlers. For example,\n\t\t * Playground web uses this to automatically display a \"Report crash\" modal.\n\t\t */\n\t\tconst exitCodePromise = runExecutionFunction().then(\n\t\t\t(exitCode) => {\n\t\t\t\t/**\n\t\t\t\t * Emit errors related to PHP script failures (exit code other than 0)\n\t\t\t\t */\n\t\t\t\tif (exitCode !== 0) {\n\t\t\t\t\tthis.dispatchEvent({\n\t\t\t\t\t\ttype: 'request.error',\n\t\t\t\t\t\terror: new Error(\n\t\t\t\t\t\t\t`PHP.run() failed with exit code ${exitCode}.`\n\t\t\t\t\t\t),\n\t\t\t\t\t\t// Distinguish between PHP request and PHP-wasm errors\n\t\t\t\t\t\tsource: 'php-wasm',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn exitCode;\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\t/**\n\t\t\t\t * Emit all other errors.\n\t\t\t\t */\n\t\t\t\t// Distinguish between PHP request and PHP-wasm errors\n\t\t\t\tconst source = (error as any).source ?? 'php-wasm';\n\t\t\t\tthis.dispatchEvent({\n\t\t\t\t\ttype: 'request.error',\n\t\t\t\t\terror: error as any as Error,\n\t\t\t\t\tsource,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t);\n\n\t\treturn new StreamedPHPResponse(\n\t\t\theaders.stream,\n\t\t\tstdout.stream,\n\t\t\tstderr.stream,\n\t\t\texitCodePromise\n\t\t);\n\t}\n\n\t/**\n\t * Recursively creates a directory with the given path in the PHP filesystem.\n\t * For example, if the path is `/root/php/data`, and `/root` already exists,\n\t * it will create the directories `/root/php` and `/root/php/data`.\n\t *\n\t * @param path - The directory path to create.\n\t */\n\tmkdir(path: string) {\n\t\tconst result = FSHelpers.mkdir(this[__private__dont__use].FS, path);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * @deprecated Use mkdir instead.\n\t */\n\tmkdirTree(path: string) {\n\t\treturn FSHelpers.mkdir(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as a string.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\treadFileAsText(path: string) {\n\t\treturn FSHelpers.readFileAsText(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Reads a file from the PHP filesystem and returns it as an array buffer.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param path - The file path to read.\n\t * @returns The file contents.\n\t */\n\treadFileAsBuffer(path: string): Uint8Array {\n\t\treturn FSHelpers.readFileAsBuffer(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Overwrites data in a file in the PHP filesystem.\n\t * Creates a new file if one doesn't exist yet.\n\t *\n\t * @param path - The file path to write to.\n\t * @param data - The data to write to the file.\n\t */\n\twriteFile(path: string, data: string | Uint8Array | Buffer) {\n\t\tconst result = FSHelpers.writeFile(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tpath,\n\t\t\tdata\n\t\t);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Removes a file from the PHP filesystem.\n\t *\n\t * @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.\n\t * @param path - The file path to remove.\n\t */\n\tunlink(path: string) {\n\t\tconst result = FSHelpers.unlink(this[__private__dont__use].FS, path);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Moves a file or directory in the PHP filesystem to a\n\t * new location.\n\t *\n\t * @param oldPath The path to rename.\n\t * @param newPath The new path.\n\t */\n\tmv(fromPath: string, toPath: string) {\n\t\tconst result = FSHelpers.mv(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tfromPath,\n\t\t\ttoPath\n\t\t);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Removes a directory from the PHP filesystem.\n\t *\n\t * @param path The directory path to remove.\n\t * @param options Options for the removal.\n\t */\n\trmdir(path: string, options: RmDirOptions = { recursive: true }) {\n\t\tconst result = FSHelpers.rmdir(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tpath,\n\t\t\toptions\n\t\t);\n\t\tthis.dispatchEvent({ type: 'filesystem.write' });\n\t\treturn result;\n\t}\n\n\t/**\n\t * Lists the files and directories in the given directory.\n\t *\n\t * @param path - The directory path to list.\n\t * @param options - Options for the listing.\n\t * @returns The list of files and directories in the given directory.\n\t */\n\tlistFiles(\n\t\tpath: string,\n\t\toptions: ListFilesOptions = { prependPath: false }\n\t) {\n\t\treturn FSHelpers.listFiles(\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tpath,\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Checks if a directory exists in the PHP filesystem.\n\t *\n\t * @param path – The path to check.\n\t * @returns True if the path is a directory, false otherwise.\n\t */\n\tisDir(path: string) {\n\t\treturn FSHelpers.isDir(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Checks if a file exists in the PHP filesystem.\n\t *\n\t * @param path – The path to check.\n\t * @returns True if the path is a file, false otherwise.\n\t */\n\tisFile(path: string) {\n\t\treturn FSHelpers.isFile(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Creates a symlink in the PHP filesystem.\n\t * @param target\n\t * @param path\n\t */\n\tsymlink(target: string, path: string) {\n\t\treturn FSHelpers.symlink(this[__private__dont__use].FS, target, path);\n\t}\n\n\t/**\n\t * Checks if a path is a symlink in the PHP filesystem.\n\t *\n\t * @param path\n\t * @returns True if the path is a symlink, false otherwise.\n\t */\n\tisSymlink(path: string) {\n\t\treturn FSHelpers.isSymlink(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Reads the target of a symlink in the PHP filesystem.\n\t *\n\t * @param path\n\t * @returns The target of the symlink.\n\t */\n\treadlink(path: string) {\n\t\treturn FSHelpers.readlink(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Resolves the real path of a file in the PHP filesystem.\n\t * @param path\n\t * @returns The real path of the file.\n\t */\n\trealpath(path: string) {\n\t\treturn FSHelpers.realpath(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Checks if a file (or a directory) exists in the PHP filesystem.\n\t *\n\t * @param path - The file path to check.\n\t * @returns True if the file exists, false otherwise.\n\t */\n\tfileExists(path: string) {\n\t\treturn FSHelpers.fileExists(this[__private__dont__use].FS, path);\n\t}\n\n\t/**\n\t * Enables inline PHP runtime rotation after a certain number of requests\n\t * or an internal crash.\n\t */\n\tenableRuntimeRotation(options: {\n\t\trecreateRuntime: () => Promise<number> | number;\n\t\tmaxRequests?: number;\n\t}) {\n\t\tthis.#rotationOptions = {\n\t\t\t...this.#rotationOptions,\n\t\t\tenabled: true,\n\t\t\trecreateRuntime: options.recreateRuntime,\n\t\t\tmaxRequests: options.maxRequests ?? 400,\n\t\t};\n\t}\n\n\tprivate async rotateRuntime() {\n\t\tif (!this.#rotationOptions.enabled) {\n\t\t\tthrow new Error(\n\t\t\t\t'Runtime rotation is not enabled. Call enableRuntimeRotation() first.'\n\t\t\t);\n\t\t}\n\t\tawait this.hotSwapPHPRuntime(\n\t\t\tawait this.#rotationOptions.recreateRuntime()\n\t\t);\n\t\tthis.#rotationOptions.requestsMade = 0;\n\t\tthis.#rotationOptions.needsRotating = false;\n\t}\n\n\t/**\n\t * Hot-swaps the PHP runtime for a new one without\n\t * interrupting the operations of this PHP instance.\n\t *\n\t * @param runtime\n\t */\n\tasync hotSwapPHPRuntime(runtime: number) {\n\t\t// Once we secure the lock and have the new runtime ready,\n\t\t// the rest of the swap handler is synchronous to make sure\n\t\t// no other operations acts on the old runtime or FS.\n\t\t// If there was await anywhere here, we'd risk applyng\n\t\t// asynchronous changes to either the filesystem or the\n\t\t// old PHP runtime without propagating them to the new\n\t\t// runtime.\n\n\t\tconst oldFS = this[__private__dont__use].FS;\n\t\tconst oldRootLevelPaths = this.listFiles('/').map((file) => `/${file}`);\n\t\tconst oldSpawnProcess = this[__private__dont__use].spawnProcess;\n\n\t\t// Temporarily set CWD to / and restore it at the end of this method.\n\t\t//\n\t\t// There's a chance cleaning up old mounts via mount.unmount()\n\t\t// will attempt removing the CWD. Normally, this would throw\n\t\t// FS.ErrnoError(10) EBUSY and interrupt the PHP runtime rotation,\n\t\t// leaving us in a broken state.\n\t\t//\n\t\t// Even though removing the CWD directory is not allowed by the\n\t\t// filesystem, we don't care that much here – we're merely freeing\n\t\t// all the resources allocated by the old filesystem before it's\n\t\t// garbage collected. We are about to recreate the same filesystem\n\t\t// structure and mounts in another PHP runtime.\n\t\t//\n\t\t// Therefore, let's suspend the strict EBUSY check by setting the CWD\n\t\t// to / for the cleanup purposes. We'll attempt to restore the original\n\t\t// CWD on the new runtime once we re-apply all the mounts there. We'll\n\t\t// only have a real reason to throw an error if the CWD path does not\n\t\t// exist in the new filesystem after the rotation.\n\t\tconst oldCWD = oldFS.cwd();\n\t\toldFS.chdir('/');\n\n\t\t// Remember mounts to apply to new runtime\n\t\tconst mountHandlersToReapplyInOrder = Object.entries(this.#mounts).map(\n\t\t\t([vfsPath, mount]) => ({\n\t\t\t\tmountHandler: mount.mountHandler,\n\t\t\t\tvfsPath,\n\t\t\t})\n\t\t);\n\n\t\t// Unmount all the mount handlers in reverse order because each nested\n\t\t// mount depends upon the parent mount which preceded it.\n\t\tconst mountsToUnmountInReverseOrder = Object.values(\n\t\t\tthis.#mounts\n\t\t).reverse();\n\t\tfor (const mount of mountsToUnmountInReverseOrder) {\n\t\t\tawait mount.unmount();\n\t\t}\n\n\t\t// Kill the current runtime\n\t\ttry {\n\t\t\tthis.exit();\n\t\t} catch {\n\t\t\t// Ignore the exit-related exception\n\t\t}\n\n\t\t// Initialize the new runtime\n\t\tthis.initializeRuntime(runtime);\n\n\t\tif (oldSpawnProcess) {\n\t\t\tthis[__private__dont__use].spawnProcess = oldSpawnProcess;\n\t\t}\n\n\t\tif (this.#sapiName) {\n\t\t\tthis.setSapiName(this.#sapiName);\n\t\t}\n\n\t\t/**\n\t\t * Ensure the new PHP instance has the same file structure as the old one.\n\t\t *\n\t\t * Catch: The underlying filesystems may be completely separate but they may be\n\t\t * partially shared via NODEFS or PROXYFS mounts. We need to be careful and only\n\t\t * recreate the MEMFS directories that aren't already shared – otherwise we'll\n\t\t * write data to shared paths that other, concurrent workers may be using.\n\t\t */\n\t\tconst newFs = this[__private__dont__use].FS;\n\t\tfor (const path of oldRootLevelPaths) {\n\t\t\t// The /request directory holds per-request state that is isolated to a\n\t\t\t// single PHP instance. Let's not copy it.\n\t\t\tif (path && path !== '/request') {\n\t\t\t\tcopyMEMFSNodes(oldFS, newFs, path);\n\t\t\t}\n\t\t}\n\n\t\t// Re-mount all the mount handlers in order\n\t\tfor (const { mountHandler, vfsPath } of mountHandlersToReapplyInOrder) {\n\t\t\tthis.mkdir(vfsPath);\n\t\t\tawait this.mount(vfsPath, mountHandler);\n\t\t}\n\t\ttry {\n\t\t\tnewFs.chdir(oldCWD);\n\t\t} catch (e) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to restore CWD to ${oldCWD} after PHP runtime rotation.`,\n\t\t\t\t{\n\t\t\t\t\tcause: e,\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Mounts a filesystem to a given path in the PHP filesystem.\n\t *\n\t * @param virtualFSPath - Where to mount it in the PHP virtual filesystem.\n\t * @param mountHandler - The mount handler to use.\n\t * @return Unmount function to unmount the filesystem.\n\t */\n\tasync mount(\n\t\tvirtualFSPath: string,\n\t\tmountHandler: MountHandler\n\t): Promise<UnmountFunction> {\n\t\tconst unmountCallback = await mountHandler(\n\t\t\tthis,\n\t\t\tthis[__private__dont__use].FS,\n\t\t\tvirtualFSPath\n\t\t);\n\t\tconst mountObject = {\n\t\t\tmountHandler,\n\t\t\tunmount: async () => {\n\t\t\t\tawait unmountCallback();\n\t\t\t\tdelete this.#mounts[virtualFSPath];\n\t\t\t},\n\t\t};\n\t\tthis.#mounts[virtualFSPath] = mountObject;\n\t\treturn () => {\n\t\t\tmountObject.unmount();\n\t\t};\n\t}\n\n\t/**\n\t * Starts a PHP CLI session with given arguments.\n\t *\n\t * This method can only be used when PHP was compiled with the CLI SAPI\n\t * and it cannot be used in conjunction with `run()`.\n\t *\n\t * Once this method finishes running, the PHP instance is no\n\t * longer usable and should be discarded. This is because PHP\n\t * internally cleans up all the resources and calls exit().\n\t *\n\t * @param argv - The arguments to pass to the CLI.\n\t * @returns The exit code of the CLI session.\n\t */\n\tasync cli(\n\t\targv: string[],\n\t\toptions: { env?: Record<string, string>; cwd?: string } = {}\n\t): Promise<StreamedPHPResponse> {\n\t\tif (basename(argv[0] ?? '') !== 'php') {\n\t\t\treturn this.subProcess(argv, options);\n\t\t}\n\n\t\tif (this.#phpWasmInitCalled) {\n\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t}\n\n\t\tconst release = await this.semaphore.acquire();\n\n\t\treturn await this.#executeWithErrorHandling(() => {\n\t\t\tconst env = options.env || {};\n\t\t\tfor (const [key, value] of Object.entries(env)) {\n\t\t\t\tthis.#setEnv(key, value);\n\t\t\t}\n\t\t\t// Enforce the use of the internal php.ini file.\n\t\t\targv = [argv[0], '-c', PHP_INI_PATH, ...argv.slice(1)];\n\t\t\tfor (const arg of argv) {\n\t\t\t\tthis[__private__dont__use].ccall(\n\t\t\t\t\t'wasm_add_cli_arg',\n\t\t\t\t\tnull,\n\t\t\t\t\t[STRING],\n\t\t\t\t\t[arg]\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn this[__private__dont__use].ccall('run_cli', null, [], [], {\n\t\t\t\tasync: true,\n\t\t\t});\n\t\t})\n\t\t\t.then((response) => {\n\t\t\t\tresponse.exitCode.finally(release);\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tthis.#rotationOptions.needsRotating = true;\n\t\t\t});\n\t}\n\n\t/**\n\t * Runs an arbitrary CLI command using the spawn handler associated\n\t * with this PHP instance.\n\t *\n\t * @param argv\n\t * @param options\n\t * @returns StreamedPHPResponse.\n\t */\n\tprivate async subProcess(\n\t\targv: string[],\n\t\toptions: { env?: Record<string, string>; cwd?: string } = {}\n\t): Promise<StreamedPHPResponse> {\n\t\tconst process = this[__private__dont__use].spawnProcess(\n\t\t\targv[0],\n\t\t\targv.slice(1),\n\t\t\t{\n\t\t\t\tenv: options.env,\n\t\t\t\tcwd: options.cwd ?? this.cwd(),\n\t\t\t}\n\t\t) as ChildProcess;\n\n\t\tconst stderrStream = await createInvertedReadableStream<Uint8Array>();\n\t\tprocess.on('error', (error) => {\n\t\t\tstderrStream.controller.error(error);\n\t\t});\n\t\tprocess.stderr.on('data', (data) => {\n\t\t\tstderrStream.controller.enqueue(data);\n\t\t});\n\n\t\tconst stdoutStream = await createInvertedReadableStream<Uint8Array>();\n\t\tprocess.stdout.on('data', (data) => {\n\t\t\tstdoutStream.controller.enqueue(data);\n\t\t});\n\n\t\tprocess.on('exit', () => {\n\t\t\t// Delay until next tick to ensure we don't close the streams before\n\t\t\t// emitting the error event on the stderrStream.\n\t\t\tsetTimeout(() => {\n\t\t\t\t/**\n\t\t\t\t * Ignore any close() errors, e.g. \"stream already closed\". We just\n\t\t\t\t * need to try to call close() and forget about this subprocess.\n\t\t\t\t */\n\t\t\t\ttry {\n\t\t\t\t\tstderrStream.controller.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tstdoutStream.controller.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t}, 0);\n\t\t});\n\n\t\treturn new StreamedPHPResponse(\n\t\t\t// Headers stream\n\t\t\tnew ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t}),\n\t\t\tstdoutStream.stream,\n\t\t\tstderrStream.stream,\n\t\t\t// Exit code\n\t\t\tnew Promise((resolve) => {\n\t\t\t\tprocess.on('exit', (code) => {\n\t\t\t\t\tresolve(code);\n\t\t\t\t});\n\t\t\t})\n\t\t);\n\t}\n\n\tsetSkipShebang(shouldSkip: boolean) {\n\t\tthis[__private__dont__use].ccall(\n\t\t\t'wasm_set_skip_shebang',\n\t\t\tnull,\n\t\t\t[NUMBER],\n\t\t\t[shouldSkip ? 1 : 0]\n\t\t);\n\t}\n\n\texit(code = 0) {\n\t\tthis.dispatchEvent({\n\t\t\ttype: 'runtime.beforeExit',\n\t\t});\n\t\ttry {\n\t\t\tthis[__private__dont__use]._exit(code);\n\t\t} catch {\n\t\t\t// ignore the exit error\n\t\t}\n\n\t\t// Clean up any initialized state\n\t\tthis.#phpWasmInitCalled = false;\n\n\t\t// Delete any links between this PHP instance and the runtime\n\t\tthis.#wasmErrorsTarget = null;\n\n\t\tif (this[__private__dont__use]) {\n\t\t\tdelete this[__private__dont__use]['onMessage'];\n\t\t\tdelete this[__private__dont__use];\n\t\t}\n\t}\n\n\t[Symbol.dispose]() {\n\t\tthis.exit(0);\n\t}\n}\n\nexport function normalizeHeaders(\n\theaders: PHPRequestHeaders\n): PHPRequestHeaders {\n\tconst normalized: PHPRequestHeaders = {};\n\tfor (const key in headers) {\n\t\tnormalized[key.toLowerCase()] = headers[key];\n\t}\n\treturn normalized;\n}\n\n/**\n * Copies the MEMFS directory structure from one FS in another FS.\n * Non-MEMFS nodes are ignored.\n */\nfunction copyMEMFSNodes(\n\tsource: Emscripten.FileSystemInstance,\n\ttarget: Emscripten.FileSystemInstance,\n\tpath: string\n) {\n\tif (\n\t\tgetNodeType(source, path) !== 'memfs' ||\n\t\t!['memfs', 'missing'].includes(getNodeType(target, path))\n\t) {\n\t\treturn;\n\t}\n\n\tconst oldNode = source.lookupPath(path);\n\tif (!source.isDir(oldNode.node.mode)) {\n\t\ttarget.writeFile(path, source.readFile(path));\n\t\treturn;\n\t}\n\n\ttarget.mkdirTree(path);\n\tconst filenames = source\n\t\t.readdir(path)\n\t\t.filter((name: string) => name !== '.' && name !== '..');\n\tfor (const filename of filenames) {\n\t\tcopyMEMFSNodes(source, target, joinPaths(path, filename));\n\t}\n}\n\n/**\n * Creates a readable stream with inverted control flow,\n * based on the specified underlying source.\n *\n * In this case, inverting control flow means exposing the controller\n * so the consumer can insert data into the stream.\n *\n * @param source - The underlying source to use.\n * @returns The resulting stream and its associated controller.\n */\nasync function createInvertedReadableStream<T = BufferSource>(\n\tsource: UnderlyingSource<T> = {}\n): Promise<{\n\tstream: ReadableStream<T>;\n\tcontroller: ReadableStreamDefaultController<T>;\n}> {\n\tlet controllerResolve: (\n\t\tcontroller: ReadableStreamDefaultController<T>\n\t) => void;\n\tconst controllerPromise = new Promise<ReadableStreamDefaultController<T>>(\n\t\t(resolve) => {\n\t\t\tcontrollerResolve = resolve;\n\t\t}\n\t);\n\n\tconst stream = new ReadableStream<T>({\n\t\t...source,\n\t\tstart(controller) {\n\t\t\t// Type assertion to handle the controller type mismatch\n\t\t\tcontrollerResolve(controller as ReadableStreamDefaultController<T>);\n\t\t\tif (source.start) {\n\t\t\t\treturn source.start(controller);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t});\n\n\tconst controller = await controllerPromise;\n\n\treturn {\n\t\tstream,\n\t\tcontroller,\n\t};\n}\n\nconst getNodeType = (fs: Emscripten.FileSystemInstance, path: string) => {\n\ttry {\n\t\tconst target = fs.lookupPath(path, { follow: true });\n\t\treturn 'contents' in target.node\n\t\t\t? 'memfs'\n\t\t\t: /**\n\t\t\t\t * Could be NODEFS, PROXYFS, etc.\n\t\t\t\t */\n\t\t\t\t'not-memfs';\n\t} catch {\n\t\treturn 'missing';\n\t}\n};\n","import { PHP_INI_PATH } from './php';\nimport type { UniversalPHP } from './universal-php';\nimport { stringify, parse } from 'ini';\n\n/**\n * Reads the php.ini file and returns its entries.\n *\n * @param php The PHP instance.\n * @param entries Optional. If provided, only the specified entries will be returned.\n * @returns The php.ini entries.\n */\nexport async function getPhpIniEntries(php: UniversalPHP, entries?: string[]) {\n\tconst ini = parse(await php.readFileAsText(PHP_INI_PATH));\n\tif (entries === undefined) {\n\t\treturn ini;\n\t}\n\tconst result: Record<string, unknown> = {};\n\tfor (const key of entries) {\n\t\tresult[key] = ini[key];\n\t}\n\treturn result;\n}\n\n/**\n * Rewrites the php.ini file with the given entries.\n *\n * @param php The PHP instance.\n * @param entries The entries to write to the php.ini file.\n */\nexport async function setPhpIniEntries(\n\tphp: UniversalPHP,\n\tentries: Record<string, unknown>\n) {\n\tconst ini = parse(await php.readFileAsText(PHP_INI_PATH));\n\tfor (const [key, value] of Object.entries(entries)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tdelete ini[key];\n\t\t} else {\n\t\t\tini[key] = value;\n\t\t}\n\t}\n\tawait php.writeFile(PHP_INI_PATH, stringify(ini));\n}\n\n/**\n * Sets php.ini values to the given values, executes a callback,\n * and restores the original php.ini values. This is useful for\n * running code with temporary php.ini values, such as when\n * disabling network-related PHP functions just to run WordPress\n * installer.\n *\n * @example\n * ```ts\n *\tawait withPHPIniValues(\n *\t\tphp,\n *\t\t{\n *\t\t\tdisable_functions: 'fsockopen',\n *\t\t\tallow_url_fopen: '0',\n *\t\t},\n *\t\tasync () => await runWpInstallationWizard(php, {\n *\t\t\toptions: {},\n *\t\t})\n *\t);\n *\t```\n *\n * @param php The PHP instance.\n * @param phpIniValues The php.ini values to set.\n * @param callback The callback to execute.\n * @returns The result of the callback.\n */\nexport async function withPHPIniValues(\n\tphp: UniversalPHP,\n\tphpIniValues: Record<string, string>,\n\tcallback: () => Promise<any>\n) {\n\tconst iniBefore = await php.readFileAsText(PHP_INI_PATH);\n\ttry {\n\t\tawait setPhpIniEntries(php, phpIniValues);\n\t\treturn await callback();\n\t} finally {\n\t\tawait php.writeFile(PHP_INI_PATH, iniBefore);\n\t}\n}\n","import type { StreamedPHPResponse } from './php-response';\nimport { PHPResponse } from './php-response';\n\nexport async function printDebugDetails(\n\te: any,\n\tstreamedResponse?: StreamedPHPResponse\n) {\n\tif (streamedResponse) {\n\t\tprintResponseDebugDetails(\n\t\t\tawait PHPResponse.fromStreamedResponse(streamedResponse)\n\t\t);\n\t}\n\tawait prettyPrintFullStackTrace(e);\n}\n\n/**\n * Pretty prints the full stack trace of the error and all its causes.\n * Includes debug details for each error in the chain.\n * This is needed\n *\n * @param e\n */\nexport async function prettyPrintFullStackTrace(e: any) {\n\tlet current = e;\n\tlet isFirst = true;\n\twhile (current) {\n\t\tif (!isFirst) {\n\t\t\tprocess.stderr.write('\\nCaused by:\\n\\n');\n\t\t}\n\n\t\tprocess.stderr.write(current.originalErrorClassName ?? current.name);\n\t\tprocess.stderr.write(': ' + current.message + '\\n');\n\t\tprocess.stderr.write(\n\t\t\t(current.stack + '').split('\\n').slice(1).join('\\n')\n\t\t);\n\t\tprocess.stderr.write(`\\n`);\n\t\tif (current.response) {\n\t\t\tprintResponseDebugDetails(current.response);\n\t\t}\n\t\tif (current.phpLogs) {\n\t\t\tprocess.stderr.write(`\\n\\n==== PHP error log ====\\n\\n`);\n\t\t\tprocess.stderr.write(current.phpLogs);\n\t\t}\n\t\tcurrent = current.cause;\n\t\tisFirst = false;\n\t}\n\tprocess.stderr.write('\\n');\n}\n\nexport function printResponseDebugDetails(response: PHPResponse) {\n\t// Print a short summary of what we have:\n\tprocess.stderr.write(\n\t\t`\\n exitCode=${response.exitCode} httpStatusCode=${response.httpStatusCode} `\n\t);\n\tconst hasHeaders =\n\t\tresponse.headers && Object.keys(response.headers).length > 0;\n\tif (!hasHeaders) {\n\t\tprocess.stderr.write(`responseHeaders=(empty) `);\n\t}\n\tif (!response.text) {\n\t\tprocess.stderr.write(`stdout=(empty) `);\n\t}\n\tif (!response.errors) {\n\t\tprocess.stderr.write(`stderr=(empty) `);\n\t}\n\tprocess.stderr.write(`\\n`);\n\n\t// Print all the extended information in a separate section:\n\tif (hasHeaders) {\n\t\tprocess.stderr.write(\n\t\t\t`\\n==== PHP response headers ====\\n\\n${JSON.stringify(\n\t\t\t\tresponse.headers,\n\t\t\t\tnull,\n\t\t\t\t2\n\t\t\t)}\\n\\n`\n\t\t);\n\t}\n\n\tif (response.text) {\n\t\tprocess.stderr.write(`\\n==== PHP stdout ====\\n\\n`);\n\t\tprocess.stderr.write(response.text);\n\t}\n\n\tif (response.errors) {\n\t\tprocess.stderr.write(`\\n==== PHP stderr ====\\n\\n`);\n\t\tprocess.stderr.write(response.errors);\n\t}\n\tprocess.stderr.write(`\\n`);\n}\n","import { logger } from '@php-wasm/logger';\nimport type { CookieStore } from './php-request-handler';\n/**\n * @public\n */\nexport class HttpCookieStore implements CookieStore {\n\tcookies: Record<string, string> = {};\n\n\trememberCookiesFromResponseHeaders(headers: Record<string, string[]>) {\n\t\tif (!headers?.['set-cookie']) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const setCookie of headers['set-cookie']) {\n\t\t\ttry {\n\t\t\t\tif (!setCookie.includes('=')) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst equalsIndex = setCookie.indexOf('=');\n\t\t\t\tconst name = setCookie.substring(0, equalsIndex);\n\t\t\t\tconst value = setCookie\n\t\t\t\t\t.substring(equalsIndex + 1)\n\t\t\t\t\t.split(';')[0];\n\t\t\t\tthis.cookies[name] = value;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(e);\n\t\t\t}\n\t\t}\n\t}\n\n\tgetCookieRequestHeader() {\n\t\tconst cookiesArray: string[] = [];\n\t\tfor (const name in this.cookies) {\n\t\t\tcookiesArray.push(`${name}=${this.cookies[name]}`);\n\t\t}\n\t\treturn cookiesArray.join('; ');\n\t}\n}\n","import type { UniversalPHP } from './universal-php';\n\n/**\n * Reads a file from PHP filesystem using a stream.\n */\nexport function streamReadFileFromPHP(php: UniversalPHP, path: string) {\n\treturn new ReadableStream({\n\t\tasync pull(controller) {\n\t\t\tconst buffer = await php.readFileAsBuffer(path);\n\t\t\tcontroller.enqueue(buffer);\n\t\t\tcontroller.close();\n\t\t},\n\t});\n}\n","import { joinPaths, normalizePath } from '@php-wasm/util';\nimport { StreamedFile } from '@php-wasm/stream-compression';\nimport type { UniversalPHP } from './universal-php';\nimport { streamReadFileFromPHP } from './stream-read-file-from-php';\n\nexport type IteratePhpFilesOptions = {\n\t/**\n\t * Should yield paths relative to the root directory?\n\t * If false, all paths will be absolute.\n\t */\n\trelativePaths?: boolean;\n\n\t/**\n\t * A prefix to add to all paths.\n\t * Only used if `relativePaths` is true.\n\t */\n\tpathPrefix?: string;\n\n\t/**\n\t * A list of paths to exclude from the results.\n\t */\n\texceptPaths?: string[];\n};\n\n/**\n * Iterates over all files in a php directory and its subdirectories.\n *\n * @param php - The PHP instance.\n * @param root - The root directory to start iterating from.\n * @param options - Optional configuration.\n * @returns All files found in the tree.\n */\nexport async function* iteratePhpFiles(\n\tphp: UniversalPHP,\n\troot: string,\n\t{\n\t\trelativePaths = true,\n\t\tpathPrefix,\n\t\texceptPaths = [],\n\t}: IteratePhpFilesOptions = {}\n): AsyncGenerator<File> {\n\troot = normalizePath(root);\n\tconst stack: string[] = [root];\n\twhile (stack.length) {\n\t\tconst currentParent = stack.pop();\n\t\tif (!currentParent) {\n\t\t\treturn;\n\t\t}\n\t\tconst files = await php.listFiles(currentParent);\n\t\tfor (const file of files) {\n\t\t\tconst absPath = `${currentParent}/${file}`;\n\t\t\tif (exceptPaths.includes(absPath.substring(root.length + 1))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst isDir = await php.isDir(absPath);\n\t\t\tif (isDir) {\n\t\t\t\tstack.push(absPath);\n\t\t\t} else {\n\t\t\t\tyield new StreamedFile(\n\t\t\t\t\tstreamReadFileFromPHP(php, absPath),\n\t\t\t\t\trelativePaths\n\t\t\t\t\t\t? joinPaths(\n\t\t\t\t\t\t\t\tpathPrefix || '',\n\t\t\t\t\t\t\t\tabsPath.substring(root.length + 1)\n\t\t\t\t\t\t )\n\t\t\t\t\t\t: absPath\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { dirname, joinPaths } from '@php-wasm/util';\nimport type { UniversalPHP } from './universal-php';\n\n/**\n * Writes streamed files to PHP filesystem.\n */\nexport function writeFilesStreamToPhp(php: UniversalPHP, root: string) {\n\treturn new WritableStream({\n\t\tasync write(file: File) {\n\t\t\tconst filePath = joinPaths(root, file.name);\n\t\t\tif (file.type === 'directory') {\n\t\t\t\tawait php.mkdir(filePath);\n\t\t\t} else {\n\t\t\t\tawait php.mkdir(dirname(filePath));\n\t\t\t\tawait php.writeFile(\n\t\t\t\t\tfilePath,\n\t\t\t\t\tnew Uint8Array(await file.arrayBuffer())\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t});\n}\n","import type { PHP } from './php';\nimport type { PHPInstanceManager, AcquiredPHP } from './php-instance-manager';\n\nexport interface SinglePHPInstanceManagerOptions {\n\t/**\n\t * Either provide an existing PHP instance...\n\t */\n\tphp?: PHP;\n\t/**\n\t * ...or a factory to create one on demand.\n\t */\n\tphpFactory?: () => Promise<PHP>;\n}\n\n/**\n * A minimal PHP instance manager that manages a single PHP instance.\n *\n * Unlike PHPProcessManager, this does not maintain a pool of instances\n * or implement concurrency control. It simply returns the same PHP\n * instance for every request.\n *\n * This is suitable for CLI contexts where:\n * - Only one PHP instance is needed\n * - Runtime rotation is handled separately via php.enableRuntimeRotation()\n * - Concurrency is not a concern (each worker has its own instance)\n */\nexport class SinglePHPInstanceManager implements PHPInstanceManager {\n\tprivate php: PHP | undefined;\n\tprivate phpPromise: Promise<PHP> | undefined;\n\tprivate phpFactory?: () => Promise<PHP>;\n\tprivate isAcquired = false;\n\n\tconstructor(options: SinglePHPInstanceManagerOptions) {\n\t\tif (!options.php && !options.phpFactory) {\n\t\t\tthrow new Error(\n\t\t\t\t'SinglePHPInstanceManager requires either php or phpFactory'\n\t\t\t);\n\t\t}\n\t\tthis.php = options.php;\n\t\tthis.phpFactory = options.phpFactory;\n\t}\n\n\tasync getPrimaryPhp(): Promise<PHP> {\n\t\tif (!this.php) {\n\t\t\tif (!this.phpPromise) {\n\t\t\t\tthis.phpPromise = this.phpFactory!().then((php) => {\n\t\t\t\t\tthis.php = php;\n\t\t\t\t\tthis.phpPromise = undefined;\n\t\t\t\t\treturn php;\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this.phpPromise;\n\t\t}\n\t\treturn this.php;\n\t}\n\n\tasync acquirePHPInstance(): Promise<AcquiredPHP> {\n\t\tif (this.isAcquired) {\n\t\t\tthrow new Error(\n\t\t\t\t'The PHP instance already acquired. SinglePHPInstanceManager cannot spawn another PHP instance since, by definition, it only manages a single PHP instance.'\n\t\t\t);\n\t\t}\n\t\tconst php = await this.getPrimaryPhp();\n\t\tthis.isAcquired = true;\n\t\treturn {\n\t\t\tphp,\n\t\t\treap: () => {\n\t\t\t\t// For single-instance manager, reap is a no-op.\n\t\t\t\t// The instance is reused for all requests.\n\t\t\t\tthis.isAcquired = false;\n\t\t\t},\n\t\t};\n\t}\n\n\tasync [Symbol.asyncDispose](): Promise<void> {\n\t\tif (this.php) {\n\t\t\tthis.php.exit();\n\t\t}\n\t}\n}\n","import { AcquireTimeoutError, Semaphore } from '@php-wasm/util';\nimport type { PHP } from './php';\nimport type { PHPInstanceManager, AcquiredPHP } from './php-instance-manager';\n\nexport type PHPFactoryOptions = {\n\tisPrimary: boolean;\n};\n\nexport type PHPFactory = (options: PHPFactoryOptions) => Promise<PHP>;\n\nexport interface ProcessManagerOptions {\n\t/**\n\t * The maximum number of PHP instances that can exist at\n\t * the same time.\n\t */\n\tmaxPhpInstances?: number;\n\t/**\n\t * The number of milliseconds to wait for a PHP instance when\n\t * we have reached the maximum number of PHP instances and\n\t * cannot spawn a new one. If the timeout is reached, we assume\n\t * all the PHP instances are deadlocked and a throw MaxPhpInstancesError.\n\t *\n\t * Default: 5000\n\t */\n\ttimeout?: number;\n\t/**\n\t * The primary PHP instance that's never killed. This instance\n\t * contains the reference filesystem used by all other PHP instances.\n\t */\n\tprimaryPhp?: PHP;\n\t/**\n\t * A factory function used for spawning new PHP instances.\n\t */\n\tphpFactory?: PHPFactory;\n}\n\nexport class MaxPhpInstancesError extends Error {\n\tconstructor(limit: number) {\n\t\tsuper(\n\t\t\t`Requested more concurrent PHP instances than the limit (${limit}).`\n\t\t);\n\t\tthis.name = this.constructor.name;\n\t}\n}\n\n/**\n * A PHP Process manager.\n *\n * Maintains:\n * * A single \"primary\" PHP instance that's never killed – it contains the\n * reference filesystem used by all other PHP instances.\n * * A pool of disposable PHP instances that are spawned to handle a single\n * request and reaped immediately after.\n *\n * When a new request comes in, PHPProcessManager yields the idle instance to\n * handle it, and immediately starts initializing a new idle instance. In other\n * words, for n concurrent requests, there are at most n+1 PHP instances\n * running at the same time.\n *\n * A slight nuance is that the first idle instance is not initialized until the\n * first concurrent request comes in. This is because many use-cases won't\n * involve parallel requests and, for those, we can avoid eagerly spinning up a\n * second PHP instance.\n *\n * This strategy is inspired by Cowboy, an Erlang HTTP server. Handling a\n * single extra request can happen immediately, while handling multiple extra\n * requests requires extra time to spin up a few PHP instances. This is a more\n * resource-friendly tradeoff than keeping 5 idle instances at all times.\n */\nexport class PHPProcessManager implements PHPInstanceManager {\n\tprivate primaryPhp?: PHP;\n\tprivate primaryPhpPromise?: Promise<AcquiredPHP>;\n\tprivate primaryIdle = true;\n\tprivate nextInstance: Promise<AcquiredPHP> | null = null;\n\t/**\n\t * All spawned PHP instances, including the primary PHP instance.\n\t * Used for bookkeeping and reaping all instances on dispose.\n\t */\n\tprivate allInstances: Promise<AcquiredPHP>[] = [];\n\tprivate phpFactory?: PHPFactory;\n\tprivate maxPhpInstances: number;\n\tprivate semaphore: Semaphore;\n\n\tconstructor(options?: ProcessManagerOptions) {\n\t\tthis.maxPhpInstances = options?.maxPhpInstances ?? 5;\n\t\tthis.phpFactory = options?.phpFactory;\n\t\tthis.primaryPhp = options?.primaryPhp;\n\t\tthis.semaphore = new Semaphore({\n\t\t\tconcurrency: this.maxPhpInstances,\n\t\t\t/**\n\t\t\t * Wait up to 5 seconds for resources to become available\n\t\t\t * before assuming that all the PHP instances are deadlocked.\n\t\t\t */\n\t\t\ttimeout: options?.timeout || 5000,\n\t\t});\n\t}\n\n\t/**\n\t * Get the primary PHP instance.\n\t *\n\t * If the primary PHP instance is not set, it will be spawned\n\t * using the provided phpFactory.\n\t *\n\t * @throws {Error} when called twice before the first call is resolved.\n\t */\n\tasync getPrimaryPhp() {\n\t\tif (!this.phpFactory && !this.primaryPhp) {\n\t\t\tthrow new Error(\n\t\t\t\t'phpFactory or primaryPhp must be set before calling getPrimaryPhp().'\n\t\t\t);\n\t\t} else if (!this.primaryPhp) {\n\t\t\tif (!this.primaryPhpPromise) {\n\t\t\t\tthis.primaryPhpPromise = this.spawn({ isPrimary: true });\n\t\t\t}\n\t\t\tthis.primaryPhp = (await this.primaryPhpPromise).php;\n\t\t\tthis.primaryPhpPromise = undefined;\n\t\t}\n\t\treturn this.primaryPhp!;\n\t}\n\n\t/**\n\t * Get a PHP instance.\n\t *\n\t * It could be either the primary PHP instance, an idle disposable PHP\n\t * instance, or a newly spawned PHP instance – depending on the resource\n\t * availability.\n\t *\n\t * @param considerPrimary - Whether to consider the primary PHP instance.\n\t * It matters because PHP.cli() sets the SAPI to CLI and\n\t * kills the entire process after it finishes running,\n\t * making the primary PHP instance non-reusable for\n\t * subsequent .run() calls. This is fine for one-off\n\t * child PHP instances, but not for the primary PHP\n\t * that's meant to continue working for the entire duration\n\t * of the ProcessManager lifetime. Therefore, we don't\n\t * consider the primary PHP instance by default unless\n\t * the caller explicitly requests it.\n\t *\n\t * @throws {MaxPhpInstancesError} when the maximum number of PHP instances is reached\n\t * and the waiting timeout is exceeded.\n\t */\n\tasync acquirePHPInstance({\n\t\tconsiderPrimary = false,\n\t}: {\n\t\tconsiderPrimary?: boolean;\n\t} = {}): Promise<AcquiredPHP> {\n\t\t/**\n\t\t * First and foremost, make sure we have the primary PHP instance in place.\n\t\t * We may not actually acquire it. We just need it to exist.\n\t\t *\n\t\t * @TODO: Re-evaluate why we need it to exist. Should spawn() be just more\n\t\t * lenient with its \"another primary instance already started spawning\"\n\t\t * check?\n\t\t */\n\t\tif (!this.primaryPhp) {\n\t\t\tawait this.getPrimaryPhp();\n\t\t}\n\n\t\tif (this.primaryIdle && considerPrimary) {\n\t\t\tthis.primaryIdle = false;\n\t\t\treturn {\n\t\t\t\tphp: await this.getPrimaryPhp(),\n\t\t\t\treap: () => {\n\t\t\t\t\tthis.primaryIdle = true;\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t/**\n\t\t * nextInstance is null:\n\t\t *\n\t\t * * Before the first concurrent getInstance() call\n\t\t * * When the last getInstance() call did not have enough\n\t\t * budget left to optimistically start spawning the next\n\t\t * instance.\n\t\t */\n\t\tconst acquiredPHP =\n\t\t\tthis.nextInstance || this.spawn({ isPrimary: false });\n\n\t\t/**\n\t\t * Start spawning the next instance if there's still room. We can't\n\t\t * just always spawn the next instance because spawn() can fail\n\t\t * asynchronously and then we'll get an unhandled promise rejection.\n\t\t */\n\t\tif (this.semaphore.remaining > 0) {\n\t\t\tthis.nextInstance = this.spawn({ isPrimary: false });\n\t\t} else {\n\t\t\tthis.nextInstance = null;\n\t\t}\n\t\treturn await acquiredPHP;\n\t}\n\n\t/**\n\t * Initiated spawning of a new PHP instance.\n\t * This function is synchronous on purpose – it needs to synchronously\n\t * add the spawn promise to the allInstances array without waiting\n\t * for PHP to spawn.\n\t */\n\tprivate spawn(factoryArgs: PHPFactoryOptions): Promise<AcquiredPHP> {\n\t\tif (factoryArgs.isPrimary && this.allInstances.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t'Requested spawning a primary PHP instance when another primary instance already started spawning.'\n\t\t\t);\n\t\t}\n\t\tconst spawned = this.doSpawn(factoryArgs);\n\t\tthis.allInstances.push(spawned);\n\t\tconst pop = () => {\n\t\t\tthis.allInstances = this.allInstances.filter(\n\t\t\t\t(instance) => instance !== spawned\n\t\t\t);\n\t\t};\n\t\treturn spawned\n\t\t\t.catch((rejection) => {\n\t\t\t\tpop();\n\t\t\t\tthrow rejection;\n\t\t\t})\n\t\t\t.then((result) => ({\n\t\t\t\t...result,\n\t\t\t\treap: () => {\n\t\t\t\t\tpop();\n\t\t\t\t\tresult.reap();\n\t\t\t\t},\n\t\t\t}));\n\t}\n\n\t/**\n\t * Actually acquires the lock and spawns a new PHP instance.\n\t */\n\tprivate async doSpawn(\n\t\tfactoryArgs: PHPFactoryOptions\n\t): Promise<AcquiredPHP> {\n\t\tlet release: () => void;\n\t\ttry {\n\t\t\trelease = await this.semaphore.acquire();\n\t\t} catch (error) {\n\t\t\tif (error instanceof AcquireTimeoutError) {\n\t\t\t\tthrow new MaxPhpInstancesError(this.maxPhpInstances);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\ttry {\n\t\t\tconst php = await this.phpFactory!(factoryArgs);\n\t\t\treturn {\n\t\t\t\tphp,\n\t\t\t\treap() {\n\t\t\t\t\tphp.exit();\n\t\t\t\t\trelease();\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (e) {\n\t\t\trelease();\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync [Symbol.asyncDispose]() {\n\t\tif (this.primaryPhp) {\n\t\t\tthis.primaryPhp.exit();\n\t\t}\n\t\tawait Promise.all(\n\t\t\tthis.allInstances.map((instance) =>\n\t\t\t\tinstance.then(({ reap }) => reap())\n\t\t\t)\n\t\t);\n\t}\n}\n","export const SupportedPHPVersions = [\n\t'8.5',\n\t'8.4',\n\t'8.3',\n\t'8.2',\n\t'8.1',\n\t'8.0',\n\t'7.4',\n\t'7.3',\n\t'7.2',\n] as const;\nexport const LatestSupportedPHPVersion = SupportedPHPVersions[0];\nexport const SupportedPHPVersionsList = SupportedPHPVersions as any as string[];\nexport type SupportedPHPVersion = (typeof SupportedPHPVersions)[number];\n","/**\n * The default base used to convert a path into the URL object.\n */\nexport const DEFAULT_BASE_URL = 'http://example.com';\n\n/**\n * Returns a string representing the path, query, and\n * fragment of the given URL.\n *\n * @example\n * ```js\n * const url = new URL('http://example.com/foo/bar?baz=qux#quux');\n * toRelativeUrl(url); // '/foo/bar?baz=qux#quux'\n * ```\n *\n * @param url The URL.\n * @returns The path, query, and fragment.\n */\nexport function toRelativeUrl(url: URL): string {\n\t/**\n\t * The origin of an about:blank URL is a string \"null\". The URL is not\n\t * relative, but there's also nothing we can do to make it \"more relative\"\n\t * so let's just bale out and return the URL as is.\n\t *\n\t * @see https://html.spec.whatwg.org/multipage/browsers.html#concept-origin (Opaque origins)\n\t */\n\tif (url.origin === 'null') {\n\t\treturn url.toString();\n\t}\n\treturn url.toString().substring(url.origin.length);\n}\n\n/**\n * Removes the given prefix from the given path.\n *\n * @example\n * ```js\n * removePathPrefix('/foo/bar', '/foo'); // '/bar'\n * removePathPrefix('/bar', '/foo'); // '/bar'\n * ```\n *\n * @param path The path to remove the prefix from.\n * @param prefix The prefix to remove.\n * @returns Path with the prefix removed.\n */\nexport function removePathPrefix(path: string, prefix: string): string {\n\tif (!prefix || !path.startsWith(prefix)) {\n\t\treturn path;\n\t}\n\treturn path.substring(prefix.length);\n}\n\n/**\n * Ensures the given path has the given prefix.\n *\n * @example\n * ```js\n * ensurePathPrefix('/bar', '/foo'); // '/foo/bar'\n * ensurePathPrefix('/foo/bar', '/foo'); // '/foo/bar'\n * ```\n *\n * @param path\n * @param prefix\n * @returns Path with the prefix added.\n */\nexport function ensurePathPrefix(path: string, prefix: string): string {\n\tif (!prefix || path.startsWith(prefix)) {\n\t\treturn path;\n\t}\n\treturn prefix + path;\n}\n","/**\n * Encodes a multipart/form-data request body.\n *\n * @param data - The form data to encode.\n * @returns The encoded body and a correctly formatted content type header.\n */\nexport async function encodeAsMultipart(\n\tdata: Record<string, string | Uint8Array | File>\n) {\n\tconst boundary = `----${Math.random().toString(36).slice(2)}`;\n\tconst contentType = `multipart/form-data; boundary=${boundary}`;\n\n\tconst textEncoder = new TextEncoder();\n\tconst parts: (string | Uint8Array)[] = [];\n\tfor (const [name, value] of Object.entries(data)) {\n\t\tparts.push(`--${boundary}\\r\\n`);\n\t\tparts.push(`Content-Disposition: form-data; name=\"${name}\"`);\n\t\tif (value instanceof File) {\n\t\t\tparts.push(`; filename=\"${value.name}\"`);\n\t\t}\n\t\tparts.push(`\\r\\n`);\n\t\tif (value instanceof File) {\n\t\t\tparts.push(`Content-Type: application/octet-stream`);\n\t\t\tparts.push(`\\r\\n`);\n\t\t}\n\t\tparts.push(`\\r\\n`);\n\t\tif (value instanceof File) {\n\t\t\tparts.push(await fileToUint8Array(value));\n\t\t} else {\n\t\t\tparts.push(value);\n\t\t}\n\t\tparts.push(`\\r\\n`);\n\t}\n\tparts.push(`--${boundary}--\\r\\n`);\n\n\tconst length = parts.reduce((acc, part) => acc + part.length, 0);\n\tconst bytes = new Uint8Array(length);\n\tlet offset = 0;\n\tfor (const part of parts) {\n\t\tbytes.set(\n\t\t\ttypeof part === 'string' ? textEncoder.encode(part) : part,\n\t\t\toffset\n\t\t);\n\t\toffset += part.length;\n\t}\n\treturn { bytes, contentType };\n}\n\nfunction fileToUint8Array(file: File): Promise<Uint8Array> {\n\t/**\n\t * @mbuella: Use File.arrayBuffer() to get a Uint8Array from a file, avoiding FileReader\n\t * which is browser-specific. This method is supported in major browsers and NodeJS/Deno runtimes.\n\t */\n\treturn file.arrayBuffer().then((fileBuffer) => new Uint8Array(fileBuffer));\n}\n","import { dirname, joinPaths } from '@php-wasm/util';\nimport {\n\tensurePathPrefix,\n\ttoRelativeUrl,\n\tremovePathPrefix,\n\tDEFAULT_BASE_URL,\n} from './urls';\nimport type { PHP, PHPExecutionFailureError } from './php';\nimport { normalizeHeaders } from './php';\nimport { PHPResponse } from './php-response';\nimport type { PHPRequest, PHPRunOptions } from './universal-php';\nimport { encodeAsMultipart } from './encode-as-multipart';\nimport type { PHPFactoryOptions } from './php-process-manager';\nimport { MaxPhpInstancesError, PHPProcessManager } from './php-process-manager';\nimport type { PHPInstanceManager, AcquiredPHP } from './php-instance-manager';\nimport { SinglePHPInstanceManager } from './single-php-instance-manager';\nimport { HttpCookieStore } from './http-cookie-store';\nimport mimeTypes from './mime-types.json';\n\nexport type RewriteRule = {\n\tmatch: RegExp;\n\treplacement: string;\n};\n\nexport type FileNotFoundToResponse = {\n\ttype: 'response';\n\tresponse: PHPResponse;\n};\nexport type FileNotFoundToInternalRedirect = {\n\ttype: 'internal-redirect';\n\turi: string;\n};\nexport type FileNotFoundTo404 = { type: '404' };\n\nexport type FileNotFoundAction =\n\t| FileNotFoundToResponse\n\t| FileNotFoundToInternalRedirect\n\t| FileNotFoundTo404;\n\nexport type FileNotFoundGetActionCallback = (\n\trelativePath: string\n) => FileNotFoundAction;\n\n/**\n * Interface for cookie storage implementations.\n * This allows different cookie handling strategies to be used with the PHP request handler.\n */\nexport interface CookieStore {\n\t/**\n\t * Processes and stores cookies from response headers\n\t * @param headers Response headers containing Set-Cookie directives\n\t */\n\trememberCookiesFromResponseHeaders(headers: Record<string, string[]>): void;\n\n\t/**\n\t * Gets the cookie header string for the next request\n\t * @returns Formatted cookie header string\n\t */\n\tgetCookieRequestHeader(): string;\n}\n\ninterface BaseConfiguration {\n\t/**\n\t * The directory in the PHP filesystem where the server will look\n\t * for the files to serve. Default: `/var/www`.\n\t */\n\tdocumentRoot?: string;\n\t/**\n\t * Request Handler URL. Used to populate $_SERVER details like HTTP_HOST.\n\t */\n\tabsoluteUrl?: string;\n\n\t/**\n\t * Rewrite rules\n\t */\n\trewriteRules?: RewriteRule[];\n\n\t/**\n\t * A callback that decides how to handle a file-not-found condition for a\n\t * given request URI.\n\t */\n\tgetFileNotFoundAction?: FileNotFoundGetActionCallback;\n}\n\nexport type PHPRequestHandlerFactoryArgs = PHPFactoryOptions & {\n\trequestHandler: PHPRequestHandler;\n};\n\nexport type PHPRequestHandlerConfiguration = BaseConfiguration & {\n\tcookieStore?: CookieStore | false;\n\n\t// One of the following must be provided:\n\n\t/**\n\t * Provide a single PHP instance directly.\n\t * PHPRequestHandler will create a SinglePHPInstanceManager internally.\n\t * This is the simplest option for CLI contexts with a single PHP instance.\n\t */\n\tphp?: PHP;\n\n\t/**\n\t * Provide a factory function to create PHP instances.\n\t * PHPRequestHandler will create a PHPProcessManager internally.\n\t */\n\tphpFactory?: (requestHandler: PHPRequestHandlerFactoryArgs) => Promise<PHP>;\n\n\t/**\n\t * The maximum number of PHP instances that can exist at\n\t * the same time. Only used when phpFactory is provided.\n\t */\n\tmaxPhpInstances?: number;\n};\n\n/**\n * Handles HTTP requests using PHP runtime as a backend.\n *\n * @public\n * @example Use PHPRequestHandler implicitly with a new PHP instance:\n * ```js\n * import { PHP } from '@php-wasm/web';\n *\n * const php = await PHP.load( '7.4', {\n * requestHandler: {\n * // PHP FS path to serve the files from:\n * documentRoot: '/www',\n *\n * // Used to populate $_SERVER['SERVER_NAME'] etc.:\n * absoluteUrl: 'http://127.0.0.1'\n * }\n * } );\n *\n * php.mkdirTree('/www');\n * php.writeFile('/www/index.php', '<?php echo \"Hi from PHP!\"; ');\n *\n * const response = await php.request({ path: '/index.php' });\n * console.log(response.text);\n * // \"Hi from PHP!\"\n * ```\n *\n * @example Explicitly create a PHPRequestHandler instance and run a PHP script:\n * ```js\n * import {\n * loadPHPRuntime,\n * PHP,\n * PHPRequestHandler,\n * getPHPLoaderModule,\n * } from '@php-wasm/web';\n *\n * const runtime = await loadPHPRuntime( await getPHPLoaderModule('7.4') );\n * const php = new PHP( runtime );\n *\n * php.mkdirTree('/www');\n * php.writeFile('/www/index.php', '<?php echo \"Hi from PHP!\"; ');\n *\n * const server = new PHPRequestHandler(php, {\n * // PHP FS path to serve the files from:\n * documentRoot: '/www',\n *\n * // Used to populate $_SERVER['SERVER_NAME'] etc.:\n * absoluteUrl: 'http://127.0.0.1'\n * });\n *\n * const response = server.request({ path: '/index.php' });\n * console.log(response.text);\n * // \"Hi from PHP!\"\n * ```\n */\nexport class PHPRequestHandler implements AsyncDisposable {\n\t#DOCROOT: string;\n\t#PROTOCOL: string;\n\t#HOSTNAME: string;\n\t#PORT: number;\n\t#HOST: string;\n\t#PATHNAME: string;\n\t#ABSOLUTE_URL: string;\n\t#cookieStore: CookieStore | false;\n\trewriteRules: RewriteRule[];\n\t/**\n\t * The instance manager used for PHP instance lifecycle.\n\t * This is either a provided instanceManager or a PHPProcessManager\n\t * created from the phpFactory.\n\t */\n\tinstanceManager: PHPInstanceManager;\n\tgetFileNotFoundAction: FileNotFoundGetActionCallback;\n\n\t/**\n\t * The request handler needs to decide whether to serve a static asset or\n\t * run the PHP interpreter. For static assets it should just reuse the primary\n\t * PHP even if there's 50 concurrent requests to serve. However, for\n\t * dynamic PHP requests, it needs to grab an available interpreter.\n\t * Therefore, it cannot just accept PHP as an argument as serving requests\n\t * requires access to ProcessManager.\n\t *\n\t * @param php - The PHP instance.\n\t * @param config - Request Handler configuration.\n\t */\n\tconstructor(config: PHPRequestHandlerConfiguration) {\n\t\tconst {\n\t\t\tdocumentRoot = '/www/',\n\t\t\tabsoluteUrl = typeof location === 'object'\n\t\t\t\t? location.href\n\t\t\t\t: DEFAULT_BASE_URL,\n\t\t\trewriteRules = [],\n\t\t\tgetFileNotFoundAction = () => ({ type: '404' }),\n\t\t} = config;\n\n\t\tconst setChroot = (php: PHP) => {\n\t\t\t// Always set managed PHP's cwd to the document root.\n\t\t\tif (!php.isDir(documentRoot)) {\n\t\t\t\tphp.mkdir(documentRoot);\n\t\t\t}\n\t\t\tphp.chdir(documentRoot);\n\n\t\t\t// @TODO: Decouple PHP and request handler\n\t\t\t(php as any).requestHandler = this;\n\t\t};\n\n\t\tif (config.php) {\n\t\t\tsetChroot(config.php);\n\t\t\tthis.instanceManager = new SinglePHPInstanceManager({\n\t\t\t\tphp: config.php,\n\t\t\t});\n\t\t} else if (config.phpFactory) {\n\t\t\tthis.instanceManager = new PHPProcessManager({\n\t\t\t\tphpFactory: async (info) => {\n\t\t\t\t\tconst php = await config.phpFactory!({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\trequestHandler: this,\n\t\t\t\t\t});\n\t\t\t\t\tsetChroot(php);\n\t\t\t\t\treturn php;\n\t\t\t\t},\n\t\t\t\tmaxPhpInstances: config.maxPhpInstances,\n\t\t\t});\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t'Either php or phpFactory must be provided in the configuration.'\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * By default, config.cookieStore is undefined, so we use the\n\t\t * HttpCookieStore implementation, otherwise we use the one\n\t\t * provided in the config.\n\t\t *\n\t\t * By explicitly checking for `undefined` we allow the user to pass\n\t\t * `null` as config.cookieStore and disable the cookie store.\n\t\t */\n\t\tthis.#cookieStore =\n\t\t\tconfig.cookieStore === undefined\n\t\t\t\t? new HttpCookieStore()\n\t\t\t\t: config.cookieStore;\n\t\tthis.#DOCROOT = documentRoot;\n\n\t\tconst url = new URL(absoluteUrl);\n\t\tthis.#HOSTNAME = url.hostname;\n\t\tthis.#PORT = url.port\n\t\t\t? Number(url.port)\n\t\t\t: url.protocol === 'https:'\n\t\t\t\t? 443\n\t\t\t\t: 80;\n\t\tthis.#PROTOCOL = (url.protocol || '').replace(':', '');\n\t\tconst isNonStandardPort = this.#PORT !== 443 && this.#PORT !== 80;\n\t\tthis.#HOST = [\n\t\t\tthis.#HOSTNAME,\n\t\t\tisNonStandardPort ? `:${this.#PORT}` : '',\n\t\t].join('');\n\t\tthis.#PATHNAME = url.pathname.replace(/\\/+$/, '');\n\t\tthis.#ABSOLUTE_URL = [\n\t\t\t`${this.#PROTOCOL}://`,\n\t\t\tthis.#HOST,\n\t\t\tthis.#PATHNAME,\n\t\t].join('');\n\t\tthis.rewriteRules = rewriteRules;\n\t\tthis.getFileNotFoundAction = getFileNotFoundAction;\n\t}\n\n\tasync getPrimaryPhp() {\n\t\treturn await this.instanceManager.getPrimaryPhp();\n\t}\n\n\t/**\n\t * Converts a path to an absolute URL based at the PHPRequestHandler\n\t * root.\n\t *\n\t * @param path The server path to convert to an absolute URL.\n\t * @returns The absolute URL.\n\t */\n\tpathToInternalUrl(path: string): string {\n\t\tif (!path.startsWith('/')) {\n\t\t\tpath = `/${path}`;\n\t\t}\n\t\treturn `${this.absoluteUrl}${path}`;\n\t}\n\n\t/**\n\t * Converts an absolute URL based at the PHPRequestHandler to a relative path\n\t * without the server pathname and scope.\n\t *\n\t * @param internalUrl An absolute URL based at the PHPRequestHandler root.\n\t * @returns The relative path.\n\t */\n\tinternalUrlToPath(internalUrl: string): string {\n\t\tconst url = new URL(internalUrl, 'https://playground.internal');\n\t\tif (url.pathname.startsWith(this.#PATHNAME)) {\n\t\t\turl.pathname = url.pathname.slice(this.#PATHNAME.length);\n\t\t}\n\t\treturn toRelativeUrl(url);\n\t}\n\n\t/**\n\t * The absolute URL of this PHPRequestHandler instance.\n\t */\n\tget absoluteUrl() {\n\t\treturn this.#ABSOLUTE_URL;\n\t}\n\n\t/**\n\t * The directory in the PHP filesystem where the server will look\n\t * for the files to serve. Default: `/var/www`.\n\t */\n\tget documentRoot() {\n\t\treturn this.#DOCROOT;\n\t}\n\n\t/**\n\t * Serves the request – either by serving a static file, or by\n\t * dispatching it to the PHP runtime.\n\t *\n\t * The request() method mode behaves like a web server and only works if\n\t * the PHP was initialized with a `requestHandler` option (which the online\n\t * version of WordPress Playground does by default).\n\t *\n\t * In the request mode, you pass an object containing the request information\n\t * (method, headers, body, etc.) and the path to the PHP file to run:\n\t *\n\t * ```ts\n\t * const php = PHP.load('7.4', {\n\t * \trequestHandler: {\n\t * \t\tdocumentRoot: \"/www\"\n\t * \t}\n\t * })\n\t * php.writeFile(\"/www/index.php\", `<?php echo file_get_contents(\"php://input\");`);\n\t * const result = await php.request({\n\t * \tmethod: \"GET\",\n\t * \theaders: {\n\t * \t\t\"Content-Type\": \"text/plain\"\n\t * \t},\n\t * \tbody: \"Hello world!\",\n\t * \tpath: \"/www/index.php\"\n\t * });\n\t * // result.text === \"Hello world!\"\n\t * ```\n\t *\n\t * The `request()` method cannot be used in conjunction with `cli()`.\n\t *\n\t * @example\n\t * ```js\n\t * const output = await php.request({\n\t * \tmethod: 'GET',\n\t * \turl: '/index.php',\n\t * \theaders: {\n\t * \t\t'X-foo': 'bar',\n\t * \t},\n\t * \tbody: {\n\t * \t\tfoo: 'bar',\n\t * \t},\n\t * });\n\t * console.log(output.stdout); // \"Hello world!\"\n\t * ```\n\t *\n\t * @param request - PHP Request data.\n\t */\n\tasync request(request: PHPRequest): Promise<PHPResponse> {\n\t\tconst isAbsolute = looksLikeAbsoluteUrl(request.url);\n\t\tconst originalRequestUrl = new URL(\n\t\t\t// Remove the hash part of the URL as it's not meant for the server.\n\t\t\trequest.url.split('#')[0],\n\t\t\tisAbsolute ? undefined : DEFAULT_BASE_URL\n\t\t);\n\n\t\tconst rewrittenRequestUrl = this.#applyRewriteRules(originalRequestUrl);\n\t\tconst primaryPhp = await this.getPrimaryPhp();\n\t\tlet fsPath = joinPaths(\n\t\t\tthis.#DOCROOT,\n\t\t\t/**\n\t\t\t * Turn a URL such as `https://playground/scope:my-site/wp-admin/index.php`\n\t\t\t * into a site-relative path, such as `/wp-admin/index.php`.\n\t\t\t */\n\t\t\tremovePathPrefix(\n\t\t\t\t/**\n\t\t\t\t * URL.pathname returns a URL-encoded path. We need to decode it\n\t\t\t\t * before using it as a filesystem path.\n\t\t\t\t */\n\t\t\t\tdecodeURIComponent(rewrittenRequestUrl.pathname),\n\t\t\t\tthis.#PATHNAME\n\t\t\t)\n\t\t);\n\t\tif (primaryPhp.isDir(fsPath)) {\n\t\t\t// Ensure directory URIs have a trailing slash. Otherwise,\n\t\t\t// relative URIs in index.php or index.html files are relative\n\t\t\t// to the next directory up.\n\t\t\t//\n\t\t\t// Example:\n\t\t\t// For an index page served for URI \"/settings\", we naturally expect\n\t\t\t// links to be relative to \"/settings\", but without the trailing\n\t\t\t// slash, a relative link \"edit.php\" resolves to \"/edit.php\"\n\t\t\t// rather than \"/settings/edit.php\".\n\t\t\t//\n\t\t\t// This treatment of relative links is correct behavior for the browser:\n\t\t\t// https://www.rfc-editor.org/rfc/rfc3986#section-5.2.3\n\t\t\t//\n\t\t\t// But user intent for `/settings/index.php` is that its relative\n\t\t\t// URIs are relative to `/settings/`. So we redirect to add a\n\t\t\t// trailing slash to directory URIs to meet this expecatation.\n\t\t\t//\n\t\t\t// This behavior is also necessary for WordPress to function properly.\n\t\t\t// Otherwise, when viewing the WP admin dashboard at `/wp-admin`,\n\t\t\t// links to other admin pages like `edit.php` will incorrectly\n\t\t\t// resolve to `/edit.php` rather than `/wp-admin/edit.php`.\n\t\t\tif (!fsPath.endsWith('/')) {\n\t\t\t\treturn new PHPResponse(\n\t\t\t\t\t301,\n\t\t\t\t\t{ Location: [`${rewrittenRequestUrl.pathname}/`] },\n\t\t\t\t\tnew Uint8Array(0)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// We can only satisfy requests for directories with a default file\n\t\t\t// so let's first resolve to a default path when available.\n\t\t\tfor (const possibleIndexFile of ['index.php', 'index.html']) {\n\t\t\t\tconst possibleIndexPath = joinPaths(fsPath, possibleIndexFile);\n\t\t\t\tif (primaryPhp.isFile(possibleIndexPath)) {\n\t\t\t\t\tfsPath = possibleIndexPath;\n\n\t\t\t\t\t// Include the resolved index file in the final rewritten request URL.\n\t\t\t\t\trewrittenRequestUrl.pathname = joinPaths(\n\t\t\t\t\t\trewrittenRequestUrl.pathname,\n\t\t\t\t\t\tpossibleIndexFile\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!primaryPhp.isFile(fsPath)) {\n\t\t\t/**\n\t\t\t * Try resolving a partial path.\n\t\t\t *\n\t\t\t * Example:\n\t\t\t *\n\t\t\t * – Request URL: /file.php/index.php\n\t\t\t * – Document Root: /var/www\n\t\t\t *\n\t\t\t * If /var/www/file.php/index.php does not exist, but /var/www/file.php does,\n\t\t\t * use /var/www/file.php. This is also what Apache and PHP Dev Server do.\n\t\t\t */\n\t\t\tlet pathToTry = rewrittenRequestUrl.pathname;\n\t\t\twhile (\n\t\t\t\tpathToTry.startsWith('/') &&\n\t\t\t\tpathToTry !== dirname(pathToTry)\n\t\t\t) {\n\t\t\t\tpathToTry = dirname(pathToTry);\n\t\t\t\tconst resolvedPathToTry = joinPaths(this.#DOCROOT, pathToTry);\n\t\t\t\tif (\n\t\t\t\t\tprimaryPhp.isFile(resolvedPathToTry) &&\n\t\t\t\t\t// Only run partial path resolution for PHP files.\n\t\t\t\t\tresolvedPathToTry.endsWith('.php')\n\t\t\t\t) {\n\t\t\t\t\tfsPath = joinPaths(this.#DOCROOT, pathToTry);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!primaryPhp.isFile(fsPath)) {\n\t\t\tconst fileNotFoundAction = this.getFileNotFoundAction(\n\t\t\t\trewrittenRequestUrl.pathname\n\t\t\t);\n\t\t\tswitch (fileNotFoundAction.type) {\n\t\t\t\tcase 'response':\n\t\t\t\t\treturn fileNotFoundAction.response;\n\t\t\t\tcase 'internal-redirect':\n\t\t\t\t\tfsPath = joinPaths(this.#DOCROOT, fileNotFoundAction.uri);\n\t\t\t\t\tbreak;\n\t\t\t\tcase '404':\n\t\t\t\t\treturn PHPResponse.forHttpCode(404);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'Unsupported file-not-found action type: ' +\n\t\t\t\t\t\t\t// Cast because TS asserts the remaining possibility is `never`\n\t\t\t\t\t\t\t`'${\n\t\t\t\t\t\t\t\t(fileNotFoundAction as FileNotFoundAction).type\n\t\t\t\t\t\t\t}'`\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// We need to confirm that the current target file exists because\n\t\t// file-not-found fallback actions may redirect to non-existent files.\n\t\tif (primaryPhp.isFile(fsPath)) {\n\t\t\tif (fsPath.endsWith('.php')) {\n\t\t\t\tconst response = await this.#spawnPHPAndDispatchRequest(\n\t\t\t\t\trequest,\n\t\t\t\t\toriginalRequestUrl,\n\t\t\t\t\trewrittenRequestUrl,\n\t\t\t\t\tfsPath\n\t\t\t\t);\n\n\t\t\t\t/**\n\t\t\t\t * If the response is but the exit code is non-zero, let's rewrite the\n\t\t\t\t * HTTP status code as 500. We're acting as a HTTP server here and\n\t\t\t\t * this behavior is in line with what Nginx and Apache do.\n\t\t\t\t */\n\t\t\t\tif (response.ok() && response.exitCode !== 0) {\n\t\t\t\t\treturn new PHPResponse(\n\t\t\t\t\t\t500,\n\t\t\t\t\t\tresponse.headers,\n\t\t\t\t\t\tresponse.bytes,\n\t\t\t\t\t\tresponse.errors,\n\t\t\t\t\t\tresponse.exitCode\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn response;\n\t\t\t} else {\n\t\t\t\treturn this.#serveStaticFile(primaryPhp, fsPath);\n\t\t\t}\n\t\t} else {\n\t\t\treturn PHPResponse.forHttpCode(404);\n\t\t}\n\t}\n\n\t/**\n\t * Apply the rewrite rules to the original request URL.\n\t *\n\t * @param originalRequestUrl - The original request URL.\n\t * @returns The rewritten request URL.\n\t */\n\t#applyRewriteRules(originalRequestUrl: URL): URL {\n\t\tconst siteRelativePath = removePathPrefix(\n\t\t\tdecodeURIComponent(originalRequestUrl.pathname),\n\t\t\tthis.#PATHNAME\n\t\t);\n\t\tconst rewrittenRequestPath = applyRewriteRules(\n\t\t\tsiteRelativePath,\n\t\t\tthis.rewriteRules\n\t\t);\n\t\tconst rewrittenRequestUrl = new URL(\n\t\t\tjoinPaths(this.#PATHNAME, rewrittenRequestPath),\n\t\t\toriginalRequestUrl.toString()\n\t\t);\n\t\t// Merge the query string parameters from the original request URL.\n\t\tfor (const [key, value] of originalRequestUrl.searchParams.entries()) {\n\t\t\trewrittenRequestUrl.searchParams.append(key, value);\n\t\t}\n\t\treturn rewrittenRequestUrl;\n\t}\n\n\t/**\n\t * Serves a static file from the PHP filesystem.\n\t *\n\t * @param fsPath - Absolute path of the static file to serve.\n\t * @returns The response.\n\t */\n\t#serveStaticFile(php: PHP, fsPath: string): PHPResponse {\n\t\tconst arrayBuffer = php.readFileAsBuffer(fsPath);\n\t\treturn new PHPResponse(\n\t\t\t200,\n\t\t\t{\n\t\t\t\t'content-length': [`${arrayBuffer.byteLength}`],\n\t\t\t\t// @TODO: Infer the content-type from the arrayBuffer instead of the\n\t\t\t\t// file path. The code below won't return the correct mime-type if the\n\t\t\t\t// extension was tampered with.\n\t\t\t\t'content-type': [inferMimeType(fsPath)],\n\t\t\t\t'accept-ranges': ['bytes'],\n\t\t\t\t'cache-control': ['public, max-age=0'],\n\t\t\t},\n\t\t\tarrayBuffer\n\t\t);\n\t}\n\n\t/**\n\t * Spawns a new PHP instance and dispatches a request to it.\n\t */\n\tasync #spawnPHPAndDispatchRequest(\n\t\trequest: PHPRequest,\n\t\toriginalRequestUrl: URL,\n\t\trewrittenRequestUrl: URL,\n\t\tscriptPath: string\n\t): Promise<PHPResponse> {\n\t\tlet spawnedPHP: AcquiredPHP | undefined = undefined;\n\t\ttry {\n\t\t\tspawnedPHP = await this.instanceManager!.acquirePHPInstance({\n\t\t\t\tconsiderPrimary: true,\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tif (e instanceof MaxPhpInstancesError) {\n\t\t\t\treturn PHPResponse.forHttpCode(502);\n\t\t\t} else {\n\t\t\t\treturn PHPResponse.forHttpCode(500);\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\treturn await this.#dispatchToPHP(\n\t\t\t\tspawnedPHP.php,\n\t\t\t\trequest,\n\t\t\t\toriginalRequestUrl,\n\t\t\t\trewrittenRequestUrl,\n\t\t\t\tscriptPath\n\t\t\t);\n\t\t} finally {\n\t\t\tspawnedPHP.reap();\n\t\t}\n\t}\n\n\t/**\n\t * Runs the requested PHP file with all the request and $_SERVER\n\t * superglobals populated.\n\t *\n\t * @param request - The request.\n\t * @returns The response.\n\t */\n\tasync #dispatchToPHP(\n\t\tphp: PHP,\n\t\trequest: PHPRequest,\n\t\toriginalRequestUrl: URL,\n\t\trewrittenRequestUrl: URL,\n\t\tscriptPath: string\n\t): Promise<PHPResponse> {\n\t\tlet preferredMethod: PHPRunOptions['method'] = 'GET';\n\n\t\tconst headers: Record<string, string> = {\n\t\t\thost: this.#HOST,\n\t\t\t...normalizeHeaders(request.headers || {}),\n\t\t};\n\t\tif (this.#cookieStore) {\n\t\t\theaders['cookie'] = this.#cookieStore.getCookieRequestHeader();\n\t\t}\n\n\t\tlet body = request.body;\n\t\tif (typeof body === 'object' && !(body instanceof Uint8Array)) {\n\t\t\tpreferredMethod = 'POST';\n\t\t\tconst { bytes, contentType } = await encodeAsMultipart(body);\n\t\t\tbody = bytes;\n\t\t\theaders['content-type'] = contentType;\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await php.run({\n\t\t\t\trelativeUri: ensurePathPrefix(\n\t\t\t\t\ttoRelativeUrl(new URL(rewrittenRequestUrl.toString())),\n\t\t\t\t\tthis.#PATHNAME\n\t\t\t\t),\n\t\t\t\tprotocol: this.#PROTOCOL,\n\t\t\t\tmethod: request.method || preferredMethod,\n\t\t\t\t$_SERVER: this.prepare_$_SERVER_superglobal(\n\t\t\t\t\toriginalRequestUrl,\n\t\t\t\t\trewrittenRequestUrl,\n\t\t\t\t\tscriptPath\n\t\t\t\t),\n\t\t\t\tbody,\n\t\t\t\tscriptPath,\n\t\t\t\theaders,\n\t\t\t});\n\t\t\tif (this.#cookieStore) {\n\t\t\t\tthis.#cookieStore.rememberCookiesFromResponseHeaders(\n\t\t\t\t\tresponse.headers\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tconst executionError = error as PHPExecutionFailureError;\n\t\t\tif (executionError?.response) {\n\t\t\t\treturn executionError.response;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Computes the essential $_SERVER entries for a request.\n\t *\n\t * php_wasm.c sets some defaults, assuming it runs as a CLI script.\n\t * This function overrides them with the values correct in the request\n\t * context.\n\t *\n\t * @TODO: Consolidate the $_SERVER setting logic into a single place instead\n\t * of splitting it between the C SAPI and the TypeScript code. The PHP\n\t * class has a `.cli()` method that could take care of the CLI-specific\n\t * $_SERVER values.\n\t *\n\t * Path and URL-related $_SERVER entries are theoretically documented\n\t * at https://www.php.net/manual/en/reserved.variables.server.php,\n\t * but that page is not very helpful in practice. Here are tables derived\n\t * by interacting with PHP servers:\n\t *\n\t * ## PHP Dev Server\n\t *\n\t * Setup:\n\t * – `/home/adam/subdir/script.php` file contains `<?php phpinfo(); ?>`\n\t * – `php -S 127.0.0.1:8041` running in `/home/adam` directory\n\t * – A request is sent to `http://127.0.0.1:8041/subdir/script.php/b.php/c.php`\n\t *\n\t * Results:\n\t *\n\t * $_SERVER['REQUEST_URI'] | `/subdir/script.php/b.php/c.php`\n\t * $_SERVER['SCRIPT_NAME'] | `/subdir/script.php`\n\t * $_SERVER['SCRIPT_FILENAME']| `/home/adam/subdir/script.php`\n\t * $_SERVER['PATH_INFO'] | `/b.php/c.php`\n\t * $_SERVER['PHP_SELF'] | `/subdir/script.php/b.php/c.php`\n\t *\n\t * ## Apache – rewriting rules\n\t *\n\t * Setup:\n\t * – `/var/www/html/subdir/script.php` file contains `<?php phpinfo(); ?>`\n\t * – Apache is listening on port 8041\n\t * – The document root is `/var/www/html`\n\t * – A request is sent to `http://127.0.0.1:8041/api/v1/user/123`\n\t *\n\t * .htaccess file:\n\t *\n\t * ```apache\n\t * RewriteEngine On\n\t * RewriteRule ^api/v1/user/([0-9]+)$ /subdir/script.php?endpoint=user&id=$1 [L,QSA]\n\t * ```\n\t *\n\t * Results:\n\t *\n\t * ```\n\t * $_SERVER['REQUEST_URI'] | /api/v1/user/123\n\t * $_SERVER['SCRIPT_NAME'] | /subdir/script.php\n\t * $_SERVER['SCRIPT_FILENAME'] | /var/www/html/subdir/script.php\n\t * $_SERVER['PATH_INFO'] | (key not set)\n\t * $_SERVER['PHP_SELF'] | /subdir/script.php\n\t * $_SERVER['QUERY_STRING'] | endpoint=user&id=123\n\t * $_SERVER['REDIRECT_STATUS'] | 200\n\t * $_SERVER['REDIRECT_URL'] | /api/v1/user/123\n\t * $_SERVER['REDIRECT_QUERY_STRING'] | endpoint=user&id=123\n\t * === $_GET Variables ===\n\t * $_GET['endpoint'] | user\n\t * $_GET['id'] | 123\n\t * ```\n\t *\n\t * ## Apache – vanilla request\n\t *\n\t * Setup:\n\t * – The same as above.\n\t * – A request sent http://localhost:8041/subdir/script.php?param=value\n\t *\n\t * Results:\n\t *\n\t * ```\n\t * $_SERVER['REQUEST_URI'] | /subdir/script.php?param=value\n\t * $_SERVER['SCRIPT_NAME'] | /subdir/script.php\n\t * $_SERVER['SCRIPT_FILENAME'] | /var/www/html/subdir/script.php\n\t * $_SERVER['PATH_INFO'] | (key not set)\n\t * $_SERVER['PHP_SELF'] | /subdir/script.php\n\t * $_SERVER['REDIRECT_URL'] | (key not set)\n\t * $_SERVER['REDIRECT_STATUS'] | (key not set)\n\t * $_SERVER['QUERY_STRING'] | param=value\n\t * $_SERVER['REQUEST_METHOD'] | GET\n\t * $_SERVER['DOCUMENT_ROOT'] | /var/www/html\n\t *\n\t * === $_GET Variables ===\n\t * $_GET['param'] | value\n\t * ```\n\t */\n\tprivate prepare_$_SERVER_superglobal(\n\t\toriginalRequestUrl: URL,\n\t\trewrittenRequestUrl: URL,\n\t\tresolvedScriptPath: string\n\t): Record<string, string> {\n\t\tconst $_SERVER: Record<string, string> = {\n\t\t\tREMOTE_ADDR: '127.0.0.1',\n\t\t\tDOCUMENT_ROOT: this.#DOCROOT,\n\t\t\tHTTPS: this.#ABSOLUTE_URL.startsWith('https://') ? 'on' : '',\n\t\t};\n\n\t\t/**\n\t\t * REQUEST_URI\n\t\t *\n\t\t * The original path + query string extracted from the requested URL\n\t\t * **before** applying any URL rewriting.\n\t\t */\n\t\t$_SERVER['REQUEST_URI'] =\n\t\t\toriginalRequestUrl.pathname + originalRequestUrl.search;\n\n\t\tif (resolvedScriptPath.startsWith(this.#DOCROOT)) {\n\t\t\t/**\n\t\t\t * SCRIPT_NAME\n\t\t\t *\n\t\t\t * > Contains the current script's path. This is useful for pages\n\t\t\t * > which need to point to themselves.\n\t\t\t *\n\t\t\t * Filesystem path of the script relative to the document root.\n\t\t\t * Note this is a filesystem path so URL rewriting is not applicable here.\n\t\t\t */\n\t\t\t$_SERVER['SCRIPT_NAME'] = resolvedScriptPath.substring(\n\t\t\t\tthis.#DOCROOT.length\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * PHP_SELF – the path sourced from the final **request URL** after the\n\t\t\t * rewrite rules have been applied.\n\t\t\t *\n\t\t\t * php.net documentation is very misleading on this one:\n\t\t\t *\n\t\t\t * > The filename of the currently executing script, relative\n\t\t\t * > to the document root. For instance, $_SERVER['PHP_SELF']\n\t\t\t * > in a script at the address http://example.com/foo/bar.php\n\t\t\t * > would be /foo/bar.php.\n\t\t\t *\n\t\t\t * @see https://www.php.net/manual/en/reserved.variables.server.php#:~:text=PHP_SELF\n\t\t\t *\n\t\t\t * This is not what Apache, nor what the PHP dev server do:\n\t\t\t *\n\t\t\t * – Document Root: /var/www\n\t\t\t * – Script file: /var/www/subdir/script.php\n\t\t\t * – Requesting /subdir/script.php/b.php/c.php\n\t\t\t *\n\t\t\t * $_SERVER['PHP_SELF'] = \"/subdir/script.php/b.php/c.php\"\n\t\t\t *\n\t\t\t * So, in that regard, it is a URL path, not a filesystem path.\n\t\t\t *\n\t\t\t * When URL rewriting is involved, it's the same.\n\t\t\t *\n\t\t\t * Consider this Apache example from above:\n\t\t\t *\n\t\t\t * – Document Root: /var/www/html\n\t\t\t * – Script file: /var/www/html/subdir/script.php\n\t\t\t * – Rewrite rule: ^api/v1/user/([0-9]+)$ /subdir/script.php?endpoint=user&id=$1 [L,QSA]\n\t\t\t * – Requesting /api/v1/user/123\n\t\t\t *\n\t\t\t * $_SERVER['PHP_SELF'] = \"/subdir/script.php\"\n\t\t\t *\n\t\t\t * So, on the face value, this is a filesystem path. However, see\n\t\t\t * what happens if we slightly modify that rewrite rule to:\n\t\t\t *\n\t\t\t * – Rewrite rule: ^api/v1/user/([0-9]+)$ /subdir/script.php/next.php\n\t\t\t * ^^^^^^^^^\n\t\t\t * – Requesting /api/v1/user/123\n\t\t\t *\n\t\t\t * $_SERVER['PHP_SELF'] = \"/subdir/script.php/next.php\"\n\t\t\t *\n\t\t\t * So:\n\t\t\t * * PHP_SELF is not sourced from the filesystem path.\n\t\t\t * * PHP_SELF is sourced from the final request URL after the\n\t\t\t * rewrite rules have been applied.\n\t\t\t */\n\t\t\t$_SERVER['PHP_SELF'] = rewrittenRequestUrl.pathname;\n\n\t\t\t/**\n\t\t\t * PATH_INFO\n\t\t\t *\n\t\t\t * > Contains any client-provided pathname information trailing the actual\n\t\t\t * > script filename but preceding the query string, if available. For instance,\n\t\t\t * > if the current script was accessed via the URI http://www.example.com/php/path_info.php/some/stuff?foo=bar,\n\t\t\t * > then $_SERVER['PATH_INFO'] would contain /some/stuff.\n\t\t\t *\n\t\t\t * This **does not** include the query string.\n\t\t\t *\n\t\t\t * @see https://www.php.net/manual/en/reserved.variables.server.php#:~:text=PATH_INFO\n\t\t\t */\n\t\t\tif ($_SERVER['REQUEST_URI'].startsWith($_SERVER['SCRIPT_NAME'])) {\n\t\t\t\t$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'].substring(\n\t\t\t\t\t$_SERVER['SCRIPT_NAME'].length\n\t\t\t\t);\n\t\t\t\t// Remove the query string if present.\n\t\t\t\tif ($_SERVER['PATH_INFO'].includes('?')) {\n\t\t\t\t\t$_SERVER['PATH_INFO'] = $_SERVER['PATH_INFO'].substring(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t$_SERVER['PATH_INFO'].indexOf('?')\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * QUERY_STRING\n\t\t *\n\t\t * The query string from the original and rewritten request URLs.\n\t\t * Does not include the leading question mark.\n\t\t *\n\t\t * Note it contains all the query parameters from the original\n\t\t * URL merged with the new parameters from the rewritten request URLs.\n\t\t *\n\t\t * Example:\n\t\t * – Original request URL: /pretty/url?foo=bar&page=different-value\n\t\t * – Rewritten request URL: /pretty/url?page=pretty\n\t\t * – QUERY_STRING: page=pretty&foo=bar&page=different-value\n\t\t */\n\t\t$_SERVER['QUERY_STRING'] = rewrittenRequestUrl.search.substring(1);\n\n\t\t/**\n\t\t * There's a few relevant entries we are NOT setting here:\n\t\t *\n\t\t * – SCRIPT_FILENAME: Absolute path to the script file. It is set by\n\t\t * php_wasm.c.\n\t\t * – REDIRECT_STATUS: Apache sets it, but it's optional so we skip it.\n\t\t * – REDIRECT_URL: Apache sets it, but it's optional so we skip it.\n\t\t * – REDIRECT_QUERY_STRING: Apache sets it, but it's optional so we skip it.\n\t\t */\n\t\treturn $_SERVER;\n\t}\n\n\tasync [Symbol.asyncDispose]() {\n\t\tawait this.instanceManager[Symbol.asyncDispose]();\n\t}\n}\n\n/**\n * Naively infer a file mime type from its path.\n *\n * @todo Infer the mime type based on the file contents.\n * A naive function like this one can be inaccurate\n * and potentially have negative security consequences.\n *\n * @param path - The file path\n * @returns The inferred mime type.\n */\nexport function inferMimeType(path: string): string {\n\tconst extension = path.split('.').pop() as keyof typeof mimeTypes;\n\t// @TODO: Consider not sending a default mime type to let the browser guess\n\treturn mimeTypes[extension] || mimeTypes['_default'];\n}\n\n/**\n * Applies the given rewrite rules to the given path.\n *\n * @param path The path to apply the rules to.\n * @param rules The rules to apply.\n * @returns The path with the rules applied.\n */\nexport function applyRewriteRules(path: string, rules: RewriteRule[]): string {\n\tfor (const rule of rules) {\n\t\tif (new RegExp(rule.match).test(path)) {\n\t\t\tpath = path.replace(rule.match, rule.replacement);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn path;\n}\n\n/**\n * Checks if the given URL looks like an absolute URL.\n *\n * @param url - The URL to check.\n * @returns `true` if the URL looks like an absolute URL, `false` otherwise.\n */\nfunction looksLikeAbsoluteUrl(url: string): boolean {\n\ttry {\n\t\t// NOTE: We could just use URL.canParse() but are avoiding it here\n\t\t// because we've seen users with older Safari versions that don't support it.\n\t\t// Maybe Playground will break in other ways for them,\n\t\t// but since this is an easy, low-risk change, let's give it a try.\n\t\tnew URL(url);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","import type { PHP } from './php';\n\nexport interface RotateOptions {\n\tphp: PHP;\n\tcwd?: string;\n\trecreateRuntime: () => Promise<number> | number;\n\tmaxRequests?: number;\n}\n\n/**\n * Configures inline runtime rotation on the provided PHP instance.\n * Returns a cleanup function that disables rotation.\n *\n * @deprecated Use `php.enableRuntimeRotation()` instead.\n */\nexport function rotatePHPRuntime({\n\tphp,\n\trecreateRuntime,\n\tmaxRequests = 400,\n}: RotateOptions) {\n\treturn php.enableRuntimeRotation({\n\t\trecreateRuntime,\n\t\tmaxRequests,\n\t});\n}\n","import { dirname, joinPaths } from '@php-wasm/util';\nimport type { UniversalPHP } from './universal-php';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FileTree\n\textends Record<string, Uint8Array | string | FileTree> {}\n\nexport interface WriteFilesOptions {\n\t/**\n\t * Whether to wipe out the contents of the\n\t * root directory before writing the new files.\n\t */\n\trmRoot?: boolean;\n}\n\n/**\n * Writes multiple files to a specified directory in the Playground\n * filesystem.\n *\n * @example ```ts\n * await writeFiles(php, '/test', {\n * \t'file.txt': 'file',\n * \t'sub/file.txt': 'file',\n * \t'sub1/sub2/file.txt': 'file',\n * });\n * ```\n *\n * @param php\n * @param root\n * @param newFiles\n * @param options\n */\nexport async function writeFiles(\n\tphp: UniversalPHP,\n\troot: string,\n\tnewFiles: FileTree,\n\t{ rmRoot = false }: WriteFilesOptions = {}\n) {\n\tif (rmRoot) {\n\t\tif (await php.isDir(root)) {\n\t\t\tawait php.rmdir(root, { recursive: true });\n\t\t}\n\t}\n\tfor (const [relativePath, content] of Object.entries(newFiles)) {\n\t\tconst filePath = joinPaths(root, relativePath);\n\t\tif (!(await php.fileExists(dirname(filePath)))) {\n\t\t\tawait php.mkdir(dirname(filePath));\n\t\t}\n\t\tif (content instanceof Uint8Array || typeof content === 'string') {\n\t\t\tawait php.writeFile(filePath, content);\n\t\t} else {\n\t\t\tawait writeFiles(php, filePath, content);\n\t\t}\n\t}\n}\n","import type { PHP } from './php';\n\n/**\n * Proxy specific paths to the parent's MEMFS instance.\n * This is useful for sharing the WordPress installation\n * between the parent and child processes.\n */\nexport function proxyFileSystem(\n\tsourceOfTruth: PHP,\n\treplica: PHP,\n\tpaths: string[]\n) {\n\t// We can't just import the symbol from the library because\n\t// Playground CLI is built as ESM and php-wasm-node is built as\n\t// CJS and the imported symbols will different in the production build.\n\tconst __private__symbol = Object.getOwnPropertySymbols(sourceOfTruth)[0];\n\tfor (const path of paths) {\n\t\tif (!replica.fileExists(path)) {\n\t\t\treplica.mkdir(path);\n\t\t}\n\t\tif (!sourceOfTruth.fileExists(path)) {\n\t\t\tsourceOfTruth.mkdir(path);\n\t\t}\n\t\t// @ts-ignore\n\t\treplica[__private__symbol].FS.mount(\n\t\t\t// @ts-ignore\n\t\t\treplica[__private__symbol].PROXYFS,\n\t\t\t{\n\t\t\t\troot: path,\n\t\t\t\t// @ts-ignore\n\t\t\t\tfs: sourceOfTruth[__private__symbol].FS,\n\t\t\t},\n\t\t\tpath\n\t\t);\n\t}\n}\n\n/**\n * Answers whether the given path is to a shared filesystem.\n *\n * @param sourceOfTruth - The PHP instance that is the source of truth.\n * @param path - The path to check.\n * @returns True if the path is to a shared filesystem, false otherwise.\n */\nexport function isPathToSharedFS(sourceOfTruth: PHP, path: string) {\n\t// We can't just import the symbol from the library because\n\t// Playground CLI is built as ESM and php-wasm-node is built as\n\t// CJS and the imported symbols will different in the production build.\n\tconst __private__symbol = Object.getOwnPropertySymbols(sourceOfTruth)[0];\n\n\t// @ts-ignore\n\tconst FS = sourceOfTruth[__private__symbol].FS;\n\n\tconst fsResult = FS.lookupPath(path, { noent_okay: true });\n\treturn fsResult?.node?.isSharedFS ?? false;\n}\n","import { createSpawnHandler, splitShellCommand } from '@php-wasm/util';\nimport type { PHP } from './php';\nimport type { PHPWorker } from './php-worker';\nimport type { Remote } from './comlink-sync';\nimport { logger } from '@php-wasm/logger';\n\n/**\n * An isomorphic proc_open() handler that implements typical shell in TypeScript\n * without relying on a server runtime. It can be used in the browser and Node.js\n * alike whenever you need to spawn a PHP subprocess, query the terminal size, etc.\n * It is open for future expansion if more shell or busybox calls are needed, but\n * advanced shell features such as piping, stream redirection etc. are outside of\n * the scope of this minimal handler. If they become vital at any point, let's\n * explore bringing in an actual shell implementation or at least a proper command\n * parser.\n */\nexport function sandboxedSpawnHandlerFactory(\n\tgetPHPInstance?: () => Promise<{\n\t\tphp: PHP | Remote<PHPWorker>;\n\t\treap: () => void;\n\t}>\n) {\n\treturn createSpawnHandler(async function (args, processApi, options) {\n\t\tprocessApi.notifySpawn();\n\t\t/**\n\t\t * Blueprints v2 spawn through the Symfony Process class, which wraps the command in\n\t\t *\n\t\t * `/bin/sh -c \"exec ...\"`\n\t\t *\n\t\t * We need to unwrap it.\n\t\t *\n\t\t * We can't just call the /bin/sh binary because we're running a sandboxed shell handler with\n\t\t * no access to OS binaries. The OS binaries wouldn't be able to resolve PHP VFS paths anyway.\n\t\t */\n\t\tif (\n\t\t\targs?.[0] === '/bin/sh' &&\n\t\t\targs?.[1] === '-c' &&\n\t\t\ttypeof args[2] === 'string'\n\t\t) {\n\t\t\targs = splitShellCommand(args[2]);\n\t\t}\n\n\t\tif (args[0] === 'exec') {\n\t\t\targs.shift();\n\t\t}\n\n\t\tif (args[0].endsWith('.php') || args[0].endsWith('.phar')) {\n\t\t\targs.unshift('php');\n\t\t}\n\n\t\tconst binaryName = args[0].split('/').pop();\n\n\t\t// Mock programs required by wp-cli:\n\t\tif (\n\t\t\targs[0] === '/usr/bin/env' &&\n\t\t\targs[1] === 'stty' &&\n\t\t\targs[2] === 'size'\n\t\t) {\n\t\t\t// These numbers are hardcoded because this\n\t\t\t// spawnHandler is transmitted as a string to\n\t\t\t// the PHP backend and has no access to local\n\t\t\t// scope. It would be nice to find a way to\n\t\t\t// transfer / proxy a live object instead.\n\t\t\t// @TODO: Do not hardcode this\n\t\t\tprocessApi.stdout(`18 140`);\n\t\t\tprocessApi.exit(0);\n\t\t} else if (binaryName === 'tput' && args[1] === 'cols') {\n\t\t\tprocessApi.stdout(`140`);\n\t\t\tprocessApi.exit(0);\n\t\t} else if (binaryName === 'less') {\n\t\t\tprocessApi.on('stdin', (data) => {\n\t\t\t\tprocessApi.stdout(data);\n\t\t\t});\n\t\t\t// Exit after the stdin stream is exhausted.\n\t\t\tawait new Promise((resolve) => {\n\t\t\t\tprocessApi.childProcess.stdin.on('finish', () => {\n\t\t\t\t\tresolve(true);\n\t\t\t\t});\n\t\t\t});\n\t\t\tprocessApi.exit(0);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!['php', 'ls', 'pwd'].includes(binaryName ?? '')) {\n\t\t\t// 127 is the exit code \"for command not found\".\n\t\t\tprocessApi.exit(127);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!getPHPInstance) {\n\t\t\tlogger.warn(\n\t\t\t\t'Tried to spawn a PHP subprocess, but the sandboxed spawn handler was created without a getPHPInstance function.'\n\t\t\t);\n\t\t\tprocessApi.exit(127);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { php, reap } = await getPHPInstance();\n\n\t\ttry {\n\t\t\tif (options.cwd) {\n\t\t\t\tawait php.chdir(options.cwd as string);\n\t\t\t}\n\n\t\t\tconst cwd = await php.cwd();\n\t\t\tswitch (binaryName) {\n\t\t\t\tcase 'php': {\n\t\t\t\t\t// Figure out more about setting env, putenv(), etc.\n\t\t\t\t\tconst result = await php.cli(args, {\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\t...options.env,\n\t\t\t\t\t\t\tSCRIPT_PATH: args[1],\n\t\t\t\t\t\t\t// Set SHELL_PIPE to 0 to ensure WP-CLI formats\n\t\t\t\t\t\t\t// the output as ASCII tables.\n\t\t\t\t\t\t\t// @see https://github.com/wp-cli/wp-cli/issues/1102\n\t\t\t\t\t\t\tSHELL_PIPE: '0',\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tresult.stdout.pipeTo(\n\t\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\t\tprocessApi.stdout(chunk as any as ArrayBuffer);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tresult.stderr.pipeTo(\n\t\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\t\tprocessApi.stderr(chunk as any as ArrayBuffer);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprocessApi.exit(await result.exitCode);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'ls': {\n\t\t\t\t\tconst files = await php.listFiles(args[1] ?? cwd);\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tprocessApi.stdout(file + '\\n');\n\t\t\t\t\t}\n\t\t\t\t\t// Technical limitation of subprocesses – we need to\n\t\t\t\t\t// wait before exiting to give consumer a chance to read\n\t\t\t\t\t// the output.\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\t\t\t\t\tprocessApi.exit(0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'pwd': {\n\t\t\t\t\tprocessApi.stdout(cwd + '\\n');\n\t\t\t\t\t// Technical limitation of subprocesses – we need to\n\t\t\t\t\t// wait before exiting to give consumer a chance to read\n\t\t\t\t\t// the output.\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\t\t\t\t\tprocessApi.exit(0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\t// An exception here means the PHP runtime has crashed.\n\t\t\tprocessApi.exit(1);\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\treap();\n\t\t}\n\t});\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-misused-new */\n/* eslint-disable @typescript-eslint/no-empty-object-type */\nimport type { MessagePort as NodeMessagePort } from 'worker_threads';\n\n/**\n * Comlink library protocol extension to use synchronous messaging.\n *\n * Debugging Asyncify is too much of a burden. This extension enables exchanging\n * messages between threads synchronously so that we don't need to rely on Asyncify.\n *\n * Upsides:\n *\n * * Saves dozens-to-hundreds of hours on debugging Asyncify issues\n * * Increased reliability\n * * Useful stack traces when errors do happen.\n *\n * Downsides:\n *\n * * Fragmentation: Both synchronous and asynchronous handlers exist to get the best our of both\n * Asyncify and JSPI. * Node.js-only: This extension does not implement a Safari-friendly\n * transport. SharedArrayBuffer is an option, but\n * it requires more restrictive CORP+COEP headers which breaks, e.g., YouTube\n * embeds. Synchronous XHR might work if we really need Safari support for one of\n * the new asynchronous features, but other than that let's just skip adding new\n * asynchronous WASM features to Safari until WebKit supports stack switching.\n * * Message passing between workers is slow. Avoid using synchronous messaging for syscalls that\n * are invoked frequently and\n * handled asynchronously in the same worker.\n *\n * @see https://github.com/adamziel/js-synchronous-messaging for additional ideas.\n * @see https://github.com/WordPress/wordpress-playground/blob/9a9262cc62cc161d220a9992706b9ed2817f2eb5/packages/docs/site/docs/developers/23-architecture/07-wasm-asyncify.md\n */\ninterface SyncMessage {\n\t/** original Comlink envelope */\n\tid?: string;\n\ttype: MessageType;\n\t/** existing Comlink fields … */\n\t[k: string]: any;\n\t/** new part that carries the latch */\n\tnotifyBuffer?: SharedArrayBuffer;\n}\n\ninterface SyncTransport {\n\tafterResponseSent(ev: MessageEvent): void;\n\tsend(\n\t\tep: IsomorphicMessagePort,\n\t\tmsg: Omit<SyncMessage, 'id' | 'notifyBuffer'>,\n\t\ttransferables?: Transferable[]\n\t): WireValue;\n}\n\nexport function exposeSync(\n\tobj: any,\n\tep: Endpoint,\n\ttransport: SyncTransport,\n\tallowedOrigins: (string | RegExp)[] = ['*']\n) {\n\treturn expose(obj, ep, allowedOrigins, transport.afterResponseSent);\n}\n\n//////////////////////////////\n// 3. Consumer side //\n//////////////////////////////\n\nfunction createSyncProxy<T>(\n\tep: IsomorphicMessagePort,\n\tpath: (string | number | symbol)[] = [],\n\ttransport: SyncTransport\n): T {\n\treturn new Proxy(() => {}, {\n\t\tget(_t, prop) {\n\t\t\tif (prop === 'then') {\n\t\t\t\t// allow await‑usage without deadlocking\n\t\t\t\tif (!path.length)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tthen: (_: any, res: any) =>\n\t\t\t\t\t\t\tres(createSyncProxy(ep, [], transport)),\n\t\t\t\t\t};\n\t\t\t}\n\t\t\treturn createSyncProxy(ep, [...path, prop], transport);\n\t\t},\n\n\t\tset(_t, prop, value) {\n\t\t\tconst [v, xfer] = toWireValue(value);\n\t\t\ttransport.send(\n\t\t\t\tep,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.SET,\n\t\t\t\t\tpath: [...path, prop].map(String),\n\t\t\t\t\tvalue: v,\n\t\t\t\t},\n\t\t\t\txfer\n\t\t\t);\n\t\t\treturn true;\n\t\t},\n\n\t\tapply(_t, _thisArg, rawArgs) {\n\t\t\t// Special cases\n\t\t\tconst last = path.at(-1);\n\t\t\tif (last === 'bind')\n\t\t\t\treturn createSyncProxy(ep, path.slice(0, -1), transport);\n\n\t\t\tconst [argList, xfer] = processArguments(rawArgs);\n\t\t\tconst wire = transport.send(\n\t\t\t\tep,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.APPLY,\n\t\t\t\t\tpath: path.map(String),\n\t\t\t\t\targumentList: argList,\n\t\t\t\t},\n\t\t\t\txfer\n\t\t\t);\n\n\t\t\treturn fromWireValue(wire);\n\t\t},\n\n\t\tconstruct(_t, rawArgs) {\n\t\t\tconst [argList, xfer] = processArguments(rawArgs);\n\t\t\tconst wire = transport.send(\n\t\t\t\tep,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.CONSTRUCT,\n\t\t\t\t\tpath: path.map(String),\n\t\t\t\t\targumentList: argList,\n\t\t\t\t},\n\t\t\t\txfer\n\t\t\t);\n\t\t\treturn fromWireValue(wire);\n\t\t},\n\t}) as unknown as T;\n}\n\nexport function wrapSync<T>(\n\tep: IsomorphicMessagePort,\n\ttransport: SyncTransport\n): T {\n\treturn createSyncProxy<T>(ep, [], transport);\n}\n\n/// Transport ///\n\nexport type IsomorphicMessagePort = MessagePort | NodeMessagePort;\n\nexport class NodeSABSyncReceiveMessageTransport {\n\tprivate static receiveMessageOnPort: any;\n\n\tstatic async create() {\n\t\tif (!NodeSABSyncReceiveMessageTransport.receiveMessageOnPort) {\n\t\t\ttry {\n\t\t\t\tNodeSABSyncReceiveMessageTransport.receiveMessageOnPort =\n\t\t\t\t\trequire('worker_threads').receiveMessageOnPort;\n\t\t\t} catch {\n\t\t\t\tNodeSABSyncReceiveMessageTransport.receiveMessageOnPort =\n\t\t\t\t\tawait import('worker_threads').then(\n\t\t\t\t\t\t(m) => m.receiveMessageOnPort\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn new NodeSABSyncReceiveMessageTransport();\n\t}\n\n\tprivate constructor() {}\n\n\tafterResponseSent(ev: MessageEvent) {\n\t\tconst { notifyBuffer } = ev.data as SyncMessage;\n\t\tif (notifyBuffer) {\n\t\t\tconst view = new Int32Array(notifyBuffer);\n\t\t\tview[0] = 1;\n\t\t\tAtomics.notify(view, 0);\n\t\t}\n\t}\n\tsend(\n\t\tep: IsomorphicMessagePort,\n\t\tmsg: Omit<SyncMessage, 'id' | 'notifyBuffer'>,\n\t\ttransferables?: Transferable[]\n\t): WireValue {\n\t\t// SharedArrayBuffer = one 32‑bit cell that starts at 0.\n\t\t// The other worker will set this to 1 when it has sent the response.\n\t\tconst latch = new SharedArrayBuffer(4);\n\t\tconst view = new Int32Array(latch);\n\t\tview[0] = 0;\n\n\t\tconst id = generateUUID();\n\t\tep.postMessage(\n\t\t\t{ ...msg, id, notifyBuffer: latch },\n\t\t\ttransferables as any\n\t\t);\n\n\t\t// Synchronous pull; Node.js-only. Browsers don't support receiveMessageOnPort.\n\t\tconst timeoutMs = 5000;\n\t\tconst result = Atomics.wait(view, 0, 0, timeoutMs);\n\t\tif (result === 'timed-out') {\n\t\t\tthrow new Error('Timeout waiting for response');\n\t\t}\n\t\twhile (true) {\n\t\t\tconst res =\n\t\t\t\tNodeSABSyncReceiveMessageTransport.receiveMessageOnPort(ep);\n\t\t\tif (res.message?.id === id) {\n\t\t\t\treturn res.message;\n\t\t\t} else if (!res) {\n\t\t\t\tthrow new Error('No response received');\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Original, unmodified Comlink library from Google:\n *\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const proxyMarker = Symbol('Comlink.proxy');\nexport const createEndpoint = Symbol('Comlink.endpoint');\nexport const releaseProxy = Symbol('Comlink.releaseProxy');\nexport const finalizer = Symbol('Comlink.finalizer');\n\nconst throwMarker = Symbol('Comlink.thrown');\n\n/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface EventSource {\n\taddEventListener(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n\n\tremoveEventListener(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n}\n\nexport interface PostMessageWithOrigin {\n\tpostMessage(\n\t\tmessage: any,\n\t\ttargetOrigin: string,\n\t\ttransfer?: Transferable[]\n\t): void;\n}\n\nexport interface Endpoint extends EventSource {\n\tpostMessage(message: any, transfer?: Transferable[]): void;\n\n\tstart?: () => void;\n}\n\nexport const WireValueType = {\n\tRAW: 'RAW',\n\tPROXY: 'PROXY',\n\tTHROW: 'THROW',\n\tHANDLER: 'HANDLER',\n} as const;\n\nexport type WireValueType = typeof WireValueType;\n\nexport interface RawWireValue {\n\tid?: string;\n\ttype: WireValueType['RAW'];\n\tvalue: any;\n}\n\nexport interface HandlerWireValue {\n\tid?: string;\n\ttype: WireValueType['HANDLER'];\n\tname: string;\n\tvalue: unknown;\n}\n\nexport type WireValue = RawWireValue | HandlerWireValue;\n\nexport type MessageID = string;\n\nexport const MessageType = {\n\tGET: 'GET',\n\tSET: 'SET',\n\tAPPLY: 'APPLY',\n\tCONSTRUCT: 'CONSTRUCT',\n\tENDPOINT: 'ENDPOINT',\n\tRELEASE: 'RELEASE',\n} as const;\nexport type MessageType = typeof MessageType;\n\nexport interface GetMessage {\n\tid?: MessageID;\n\ttype: MessageType['GET'];\n\tpath: string[];\n}\n\nexport interface SetMessage {\n\tid?: MessageID;\n\ttype: MessageType['SET'];\n\tpath: string[];\n\tvalue: WireValue;\n}\n\nexport interface ApplyMessage {\n\tid?: MessageID;\n\ttype: MessageType['APPLY'];\n\tpath: string[];\n\targumentList: WireValue[];\n}\n\nexport interface ConstructMessage {\n\tid?: MessageID;\n\ttype: MessageType['CONSTRUCT'];\n\tpath: string[];\n\targumentList: WireValue[];\n}\n\nexport interface EndpointMessage {\n\tid?: MessageID;\n\ttype: MessageType['ENDPOINT'];\n}\n\nexport interface ReleaseMessage {\n\tid?: MessageID;\n\ttype: MessageType['RELEASE'];\n}\n\nexport type Message =\n\t| GetMessage\n\t| SetMessage\n\t| ApplyMessage\n\t| ConstructMessage\n\t| EndpointMessage\n\t| ReleaseMessage;\n\n/**\n * Interface of values that were marked to be proxied with `comlink.proxy()`.\n * Can also be implemented by classes.\n */\nexport interface ProxyMarked {\n\t[proxyMarker]: true;\n}\n\n/**\n * Takes a type and wraps it in a Promise, if it not already is one.\n * This is to avoid `Promise<Promise<T>>`.\n *\n * This is the inverse of `Unpromisify<T>`.\n */\ntype Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;\n/**\n * Takes a type that may be Promise and unwraps the Promise type.\n * If `P` is not a Promise, it returns `P`.\n *\n * This is the inverse of `Promisify<T>`.\n */\ntype Unpromisify<P> = P extends Promise<infer T> ? T : P;\n\n/**\n * Takes the raw type of a remote property and returns the type that is visible to the local thread\n * on the proxy.\n *\n * Note: This needs to be its own type alias, otherwise it will not distribute over unions.\n * See https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types\n */\ntype RemoteProperty<T> =\n\t// If the value is a method, comlink will proxy it automatically.\n\t// Objects are only proxied if they are marked to be proxied.\n\t// Otherwise, the property is converted to a Promise that resolves the cloned value.\n\tT extends Function | ProxyMarked ? Remote<T> : Promisify<T>;\n\n/**\n * Takes the raw type of a property as a remote thread would see it through a proxy (e.g. when\n * passed in as a function argument) and returns the type that the local thread has to supply.\n *\n * This is the inverse of `RemoteProperty<T>`.\n *\n * Note: This needs to be its own type alias, otherwise it will not distribute over unions. See\n * https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types\n */\ntype LocalProperty<T> = T extends Function | ProxyMarked\n\t? Local<T>\n\t: Unpromisify<T>;\n\n/**\n * Proxies `T` if it is a `ProxyMarked`, clones it otherwise (as handled by structured cloning and\n * transfer handlers).\n */\nexport type ProxyOrClone<T> = T extends ProxyMarked ? Remote<T> : T;\n/**\n * Inverse of `ProxyOrClone<T>`.\n */\nexport type UnproxyOrClone<T> = T extends RemoteObject<ProxyMarked>\n\t? Local<T>\n\t: T;\n\n/**\n * Takes the raw type of a remote object in the other thread and returns the type as it is visible\n * to the local thread when proxied with `Comlink.proxy()`.\n *\n * This does not handle call signatures, which is handled by the more general `Remote<T>` type.\n *\n * @template T The raw type of a remote object as seen in the other thread.\n */\nexport type RemoteObject<T> = { [P in keyof T]: RemoteProperty<T[P]> };\n/**\n * Takes the type of an object as a remote thread would see it through a proxy (e.g. when passed in\n * as a function argument) and returns the type that the local thread has to supply.\n *\n * This does not handle call signatures, which is handled by the more general `Local<T>` type.\n *\n * This is the inverse of `RemoteObject<T>`.\n *\n * @template T The type of a proxied object.\n */\nexport type LocalObject<T> = { [P in keyof T]: LocalProperty<T[P]> };\n\n/**\n * Additional special comlink methods available on each proxy returned by `Comlink.wrap()`.\n */\nexport interface ProxyMethods {\n\t[createEndpoint]: () => Promise<MessagePort>;\n\t[releaseProxy]: () => void;\n}\n\n/**\n * Takes the raw type of a remote object, function or class in the other thread and returns the\n * type as it is visible to the local thread from the proxy return value of `Comlink.wrap()` or\n * `Comlink.proxy()`.\n */\nexport type Remote<T> =\n\t// Handle properties\n\tRemoteObject<T> &\n\t\t// Handle call signature (if present)\n\t\t(T extends (...args: infer TArguments) => infer TReturn\n\t\t\t? (\n\t\t\t\t\t...args: {\n\t\t\t\t\t\t[I in keyof TArguments]: UnproxyOrClone<TArguments[I]>;\n\t\t\t\t\t}\n\t\t\t ) => Promisify<ProxyOrClone<Unpromisify<TReturn>>>\n\t\t\t: unknown) &\n\t\t// Handle construct signature (if present)\n\t\t// The return of construct signatures is always proxied (whether marked or not)\n\t\t(T extends { new (...args: infer TArguments): infer TInstance }\n\t\t\t? {\n\t\t\t\t\tnew (\n\t\t\t\t\t\t...args: {\n\t\t\t\t\t\t\t[I in keyof TArguments]: UnproxyOrClone<\n\t\t\t\t\t\t\t\tTArguments[I]\n\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t}\n\t\t\t\t\t): Promisify<Remote<TInstance>>;\n\t\t\t }\n\t\t\t: unknown) &\n\t\t// Include additional special comlink methods available on the proxy.\n\t\tProxyMethods;\n\n/**\n * Expresses that a type can be either a sync or async.\n */\ntype MaybePromise<T> = Promise<T> | T;\n\n/**\n * Takes the raw type of a remote object, function or class as a remote thread would see it through\n * a proxy (e.g. when passed in as a function argument) and returns the type the local thread has\n * to supply.\n *\n * This is the inverse of `Remote<T>`. It takes a `Remote<T>` and returns its original input `T`.\n */\nexport type Local<T> =\n\t// Omit the special proxy methods (they don't need to be supplied, comlink adds them)\n\tOmit<LocalObject<T>, keyof ProxyMethods> &\n\t\t// Handle call signatures (if present)\n\t\t(T extends (...args: infer TArguments) => infer TReturn\n\t\t\t? (\n\t\t\t\t\t...args: {\n\t\t\t\t\t\t[I in keyof TArguments]: ProxyOrClone<TArguments[I]>;\n\t\t\t\t\t}\n\t\t\t ) => // The raw function could either be sync or async, but is always proxied automatically\n\t\t\t MaybePromise<UnproxyOrClone<Unpromisify<TReturn>>>\n\t\t\t: unknown) &\n\t\t// Handle construct signature (if present)\n\t\t// The return of construct signatures is always proxied (whether marked or not)\n\t\t(T extends { new (...args: infer TArguments): infer TInstance }\n\t\t\t? {\n\t\t\t\t\tnew (\n\t\t\t\t\t\t...args: {\n\t\t\t\t\t\t\t[I in keyof TArguments]: ProxyOrClone<\n\t\t\t\t\t\t\t\tTArguments[I]\n\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t}\n\t\t\t\t\t): // The raw constructor could either be sync or async, but is always proxied automatically\n\t\t\t\t\tMaybePromise<Local<Unpromisify<TInstance>>>;\n\t\t\t }\n\t\t\t: unknown);\n\nconst isObject = (val: unknown): val is object =>\n\t(typeof val === 'object' && val !== null) || typeof val === 'function';\n\n/**\n * Customizes the serialization of certain values as determined by `canHandle()`.\n *\n * @template T The input type being handled by this transfer handler.\n * @template S The serialized type sent over the wire.\n */\nexport interface TransferHandler<T, S> {\n\t/**\n\t * Gets called for every value to determine whether this transfer handler\n\t * should serialize the value, which includes checking that it is of the right\n\t * type (but can perform checks beyond that as well).\n\t */\n\tcanHandle(value: unknown): value is T;\n\n\t/**\n\t * Gets called with the value if `canHandle()` returned `true` to produce a\n\t * value that can be sent in a message, consisting of structured-cloneable\n\t * values and/or transferrable objects.\n\t */\n\tserialize(value: T): [S, Transferable[]];\n\n\t/**\n\t * Gets called to deserialize an incoming value that was serialized in the\n\t * other thread with this transfer handler (known through the name it was\n\t * registered under).\n\t */\n\tdeserialize(value: S): T;\n}\n\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler: TransferHandler<object, MessagePort> = {\n\tcanHandle: (val): val is ProxyMarked =>\n\t\tisObject(val) && (val as ProxyMarked)[proxyMarker],\n\tserialize(obj) {\n\t\tconst { port1, port2 } = new MessageChannel();\n\t\texpose(obj, port1);\n\t\treturn [port2, [port2]];\n\t},\n\tdeserialize(port) {\n\t\tport.start();\n\t\treturn wrap(port);\n\t},\n};\n\ninterface ThrownValue {\n\t[throwMarker]: unknown; // just needs to be present\n\tvalue: unknown;\n}\ntype SerializedThrownValue =\n\t| { isError: true; value: Error }\n\t| { isError: false; value: unknown };\ntype PendingListenersMap = Map<\n\tstring,\n\t(value: WireValue | PromiseLike<WireValue>) => void\n>;\n\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler: TransferHandler<\n\tThrownValue,\n\tSerializedThrownValue\n> = {\n\tcanHandle: (value): value is ThrownValue =>\n\t\tisObject(value) && throwMarker in value,\n\tserialize({ value }) {\n\t\tlet serialized: SerializedThrownValue;\n\t\tif (value instanceof Error) {\n\t\t\tserialized = {\n\t\t\t\tisError: true,\n\t\t\t\tvalue: {\n\t\t\t\t\tmessage: value.message,\n\t\t\t\t\tname: value.name,\n\t\t\t\t\tstack: value.stack,\n\t\t\t\t},\n\t\t\t};\n\t\t} else {\n\t\t\tserialized = { isError: false, value };\n\t\t}\n\t\treturn [serialized, []];\n\t},\n\tdeserialize(serialized) {\n\t\tif (serialized.isError) {\n\t\t\tthrow Object.assign(\n\t\t\t\tnew Error(serialized.value.message),\n\t\t\t\tserialized.value\n\t\t\t);\n\t\t}\n\t\tthrow serialized.value;\n\t},\n};\n\n/**\n * Allows customizing the serialization of certain values.\n */\nexport const transferHandlers = new Map<\n\tstring,\n\tTransferHandler<unknown, unknown>\n>([\n\t['proxy', proxyTransferHandler],\n\t['throw', throwTransferHandler],\n]);\n\nfunction isAllowedOrigin(\n\tallowedOrigins: (string | RegExp)[],\n\torigin: string\n): boolean {\n\tfor (const allowedOrigin of allowedOrigins) {\n\t\tif (origin === allowedOrigin || allowedOrigin === '*') {\n\t\t\treturn true;\n\t\t}\n\t\tif (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function expose(\n\tobj: any,\n\tep: Endpoint = globalThis as any,\n\tallowedOrigins: (string | RegExp)[] = ['*'],\n\tafterResponseSent?: (ev: MessageEvent) => void\n) {\n\tep.addEventListener('message', function callback(ev: MessageEvent) {\n\t\tif (!ev || !ev.data) {\n\t\t\treturn;\n\t\t}\n\t\tif (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n\t\t\treturn;\n\t\t}\n\t\tconst { id, type, path } = {\n\t\t\tpath: [] as string[],\n\t\t\t...(ev.data as Message),\n\t\t};\n\t\tconst argumentList = (ev.data.argumentList || []).map(fromWireValue);\n\t\tlet returnValue;\n\t\ttry {\n\t\t\tconst parent = path\n\t\t\t\t.slice(0, -1)\n\t\t\t\t.reduce((obj, prop) => obj[prop], obj);\n\t\t\tconst rawValue = path.reduce((obj, prop) => obj[prop], obj);\n\t\t\tswitch (type) {\n\t\t\t\tcase MessageType.GET:\n\t\t\t\t\t{\n\t\t\t\t\t\treturnValue = rawValue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.SET:\n\t\t\t\t\t{\n\t\t\t\t\t\tparent[path.slice(-1)[0]] = fromWireValue(\n\t\t\t\t\t\t\tev.data.value\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturnValue = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.APPLY:\n\t\t\t\t\t{\n\t\t\t\t\t\treturnValue = rawValue.apply(parent, argumentList);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.CONSTRUCT:\n\t\t\t\t\t{\n\t\t\t\t\t\tconst value = new rawValue(...argumentList);\n\t\t\t\t\t\treturnValue = proxy(value);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.ENDPOINT:\n\t\t\t\t\t{\n\t\t\t\t\t\tconst { port1, port2 } = new MessageChannel();\n\t\t\t\t\t\texpose(obj, port2);\n\t\t\t\t\t\treturnValue = transfer(port1, [port1]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MessageType.RELEASE:\n\t\t\t\t\t{\n\t\t\t\t\t\treturnValue = undefined;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} catch (value) {\n\t\t\treturnValue = { value, [throwMarker]: 0 };\n\t\t}\n\t\tPromise.resolve(returnValue)\n\t\t\t.catch((value) => {\n\t\t\t\treturn { value, [throwMarker]: 0 };\n\t\t\t})\n\t\t\t.then((returnValue) => {\n\t\t\t\tconst [wireValue, transferables] = toWireValue(returnValue);\n\t\t\t\tep.postMessage({ ...wireValue, id }, transferables);\n\t\t\t\tif (type === MessageType.RELEASE) {\n\t\t\t\t\t// detach and deactive after sending release response above.\n\t\t\t\t\tep.removeEventListener('message', callback as any);\n\t\t\t\t\tcloseEndPoint(ep);\n\t\t\t\t\tif (\n\t\t\t\t\t\tfinalizer in obj &&\n\t\t\t\t\t\ttypeof obj[finalizer] === 'function'\n\t\t\t\t\t) {\n\t\t\t\t\t\tobj[finalizer]();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// Send Serialization Error To Caller\n\t\t\t\tconst [wireValue, transferables] = toWireValue({\n\t\t\t\t\tvalue: new TypeError('Unserializable return value'),\n\t\t\t\t\t[throwMarker]: 0,\n\t\t\t\t});\n\t\t\t\tep.postMessage({ ...wireValue, id }, transferables);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tafterResponseSent?.(ev);\n\t\t\t});\n\t} as any);\n\tif (ep.start) {\n\t\tep.start();\n\t}\n}\n\nfunction isMessagePort(endpoint: Endpoint): endpoint is MessagePort {\n\treturn endpoint.constructor.name === 'MessagePort';\n}\n\nfunction closeEndPoint(endpoint: Endpoint) {\n\tif (isMessagePort(endpoint)) endpoint.close();\n}\n\nexport function wrap<T>(ep: Endpoint, target?: any): Remote<T> {\n\tconst pendingListeners: PendingListenersMap = new Map();\n\n\tep.addEventListener('message', function handleMessage(ev: Event) {\n\t\tconst { data } = ev as MessageEvent;\n\t\tif (!data || !data.id) {\n\t\t\treturn;\n\t\t}\n\t\tconst resolver = pendingListeners.get(data.id);\n\t\tif (!resolver) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tresolver(data);\n\t\t} finally {\n\t\t\tpendingListeners.delete(data.id);\n\t\t}\n\t});\n\n\treturn createProxy<T>(ep, pendingListeners, [], target) as any;\n}\n\nfunction throwIfProxyReleased(isReleased: boolean) {\n\tif (isReleased) {\n\t\tthrow new Error('Proxy has been released and is not useable');\n\t}\n}\n\nfunction releaseEndpoint(ep: Endpoint) {\n\treturn requestResponseMessage(ep, new Map(), {\n\t\ttype: MessageType.RELEASE,\n\t}).then(() => {\n\t\tcloseEndPoint(ep);\n\t});\n}\n\ninterface FinalizationRegistry<T> {\n\t// @ts-ignore\n\tnew (cb: (heldValue: T) => void): FinalizationRegistry<T>;\n\tregister(\n\t\tweakItem: object,\n\t\theldValue: T,\n\t\tunregisterToken?: object | undefined\n\t): void;\n\tunregister(unregisterToken: object): void;\n}\ndeclare const FinalizationRegistry: FinalizationRegistry<Endpoint>;\n\nconst proxyCounter = new WeakMap<Endpoint, number>();\nconst proxyFinalizers =\n\t'FinalizationRegistry' in globalThis &&\n\tnew FinalizationRegistry((ep: Endpoint) => {\n\t\tconst newCount = (proxyCounter.get(ep) || 0) - 1;\n\t\tproxyCounter.set(ep, newCount);\n\t\tif (newCount === 0) {\n\t\t\treleaseEndpoint(ep);\n\t\t}\n\t});\n\nfunction registerProxy(proxy: object, ep: Endpoint) {\n\tconst newCount = (proxyCounter.get(ep) || 0) + 1;\n\tproxyCounter.set(ep, newCount);\n\tif (proxyFinalizers) {\n\t\tproxyFinalizers.register(proxy, ep, proxy);\n\t}\n}\n\nfunction unregisterProxy(proxy: object) {\n\tif (proxyFinalizers) {\n\t\tproxyFinalizers.unregister(proxy);\n\t}\n}\n\nfunction createProxy<T>(\n\tep: Endpoint,\n\tpendingListeners: PendingListenersMap,\n\tpath: (string | number | symbol)[] = [],\n\ttarget: object = function () {}\n): Remote<T> {\n\tlet isProxyReleased = false;\n\tconst proxy = new Proxy(target, {\n\t\tget(_target, prop) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\tif (prop === releaseProxy) {\n\t\t\t\treturn () => {\n\t\t\t\t\tunregisterProxy(proxy);\n\t\t\t\t\treleaseEndpoint(ep);\n\t\t\t\t\tpendingListeners.clear();\n\t\t\t\t\tisProxyReleased = true;\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (prop === 'then') {\n\t\t\t\tif (path.length === 0) {\n\t\t\t\t\treturn { then: () => proxy };\n\t\t\t\t}\n\t\t\t\tconst r = requestResponseMessage(ep, pendingListeners, {\n\t\t\t\t\ttype: MessageType.GET,\n\t\t\t\t\tpath: path.map((p) => p.toString()),\n\t\t\t\t}).then(fromWireValue);\n\t\t\t\treturn r.then.bind(r);\n\t\t\t}\n\t\t\treturn createProxy(ep, pendingListeners, [...path, prop]);\n\t\t},\n\t\tset(_target, prop, rawValue) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\t// FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n\t\t\t// boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n\t\t\tconst [value, transferables] = toWireValue(rawValue);\n\t\t\treturn requestResponseMessage(\n\t\t\t\tep,\n\t\t\t\tpendingListeners,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.SET,\n\t\t\t\t\tpath: [...path, prop].map((p) => p.toString()),\n\t\t\t\t\tvalue,\n\t\t\t\t},\n\t\t\t\ttransferables\n\t\t\t).then(fromWireValue) as any;\n\t\t},\n\t\tapply(_target, _thisArg, rawArgumentList) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\tconst last = path[path.length - 1];\n\t\t\tif ((last as any) === createEndpoint) {\n\t\t\t\treturn requestResponseMessage(ep, pendingListeners, {\n\t\t\t\t\ttype: MessageType.ENDPOINT,\n\t\t\t\t}).then(fromWireValue);\n\t\t\t}\n\t\t\t// We just pretend that `bind()` didn’t happen.\n\t\t\tif (last === 'bind') {\n\t\t\t\treturn createProxy(ep, pendingListeners, path.slice(0, -1));\n\t\t\t}\n\t\t\tconst [argumentList, transferables] =\n\t\t\t\tprocessArguments(rawArgumentList);\n\t\t\treturn requestResponseMessage(\n\t\t\t\tep,\n\t\t\t\tpendingListeners,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.APPLY,\n\t\t\t\t\tpath: path.map((p) => p.toString()),\n\t\t\t\t\targumentList,\n\t\t\t\t},\n\t\t\t\ttransferables\n\t\t\t).then(fromWireValue);\n\t\t},\n\t\tconstruct(_target, rawArgumentList) {\n\t\t\tthrowIfProxyReleased(isProxyReleased);\n\t\t\tconst [argumentList, transferables] =\n\t\t\t\tprocessArguments(rawArgumentList);\n\t\t\treturn requestResponseMessage(\n\t\t\t\tep,\n\t\t\t\tpendingListeners,\n\t\t\t\t{\n\t\t\t\t\ttype: MessageType.CONSTRUCT,\n\t\t\t\t\tpath: path.map((p) => p.toString()),\n\t\t\t\t\targumentList,\n\t\t\t\t},\n\t\t\t\ttransferables\n\t\t\t).then(fromWireValue);\n\t\t},\n\t});\n\tregisterProxy(proxy, ep);\n\treturn proxy as any;\n}\n\nfunction myFlat<T>(arr: (T | T[])[]): T[] {\n\treturn Array.prototype.concat.apply([], arr);\n}\n\nfunction processArguments(argumentList: any[]): [WireValue[], Transferable[]] {\n\tconst processed = argumentList.map(toWireValue);\n\treturn [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\n\nconst transferCache = new WeakMap<any, Transferable[]>();\nexport function transfer<T>(obj: T, transfers: Transferable[]): T {\n\ttransferCache.set(obj, transfers);\n\treturn obj;\n}\n\nexport function proxy<T extends object>(obj: T): T & ProxyMarked {\n\treturn Object.assign(obj, { [proxyMarker]: true }) as any;\n}\n\nexport function windowEndpoint(\n\tw: PostMessageWithOrigin,\n\tcontext: EventSource = globalThis,\n\ttargetOrigin = '*'\n): Endpoint {\n\treturn {\n\t\tpostMessage: (msg: any, transferables: Transferable[]) =>\n\t\t\tw.postMessage(msg, targetOrigin, transferables),\n\t\taddEventListener: context.addEventListener.bind(context),\n\t\tremoveEventListener: context.removeEventListener.bind(context),\n\t};\n}\n\nfunction toWireValue(value: any): [WireValue, Transferable[]] {\n\tfor (const [name, handler] of transferHandlers) {\n\t\tif (handler.canHandle(value)) {\n\t\t\tconst [serializedValue, transferables] = handler.serialize(value);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: WireValueType.HANDLER,\n\t\t\t\t\tname,\n\t\t\t\t\tvalue: serializedValue,\n\t\t\t\t},\n\t\t\t\ttransferables,\n\t\t\t];\n\t\t}\n\t}\n\treturn [\n\t\t{\n\t\t\ttype: WireValueType.RAW,\n\t\t\tvalue,\n\t\t},\n\t\ttransferCache.get(value) || [],\n\t];\n}\n\nfunction fromWireValue(value: WireValue): any {\n\tswitch (value.type) {\n\t\tcase WireValueType.HANDLER:\n\t\t\treturn transferHandlers.get(value.name)!.deserialize(value.value);\n\t\tcase WireValueType.RAW:\n\t\t\treturn value.value;\n\t}\n}\n\nfunction requestResponseMessage(\n\tep: Endpoint,\n\tpendingListeners: PendingListenersMap,\n\tmsg: Message,\n\ttransfers?: Transferable[]\n): Promise<WireValue> {\n\treturn new Promise((resolve) => {\n\t\tconst id = generateUUID();\n\t\tpendingListeners.set(id, resolve);\n\t\tif (ep.start) {\n\t\t\tep.start();\n\t\t}\n\t\tep.postMessage({ id, ...msg }, transfers);\n\t});\n}\n\nfunction generateUUID(): string {\n\treturn new Array(4)\n\t\t.fill(0)\n\t\t.map(() =>\n\t\t\tMath.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)\n\t\t)\n\t\t.join('-');\n}\n\n// node-adapter.ts:\n\nexport interface NodeEndpoint {\n\tpostMessage(message: any, transfer?: any[]): void;\n\ton(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n\toff(\n\t\ttype: string,\n\t\tlistener: EventListenerOrEventListenerObject,\n\t\toptions?: object\n\t): void;\n\tstart?: () => void;\n}\n\nexport function nodeEndpoint(nep: NodeEndpoint): Endpoint {\n\tconst listeners = new WeakMap();\n\treturn {\n\t\tpostMessage: nep.postMessage.bind(nep),\n\t\taddEventListener: (_, eh) => {\n\t\t\tconst l = (data: any) => {\n\t\t\t\tif ('handleEvent' in eh) {\n\t\t\t\t\teh.handleEvent({ data } as MessageEvent);\n\t\t\t\t} else {\n\t\t\t\t\teh({ data } as MessageEvent);\n\t\t\t\t}\n\t\t\t};\n\t\t\tnep.on('message', l);\n\t\t\tlisteners.set(eh, l);\n\t\t},\n\t\tremoveEventListener: (_, eh) => {\n\t\t\tconst l = listeners.get(eh);\n\t\t\tif (!l) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnep.off('message', l);\n\t\t\tlisteners.delete(eh);\n\t\t},\n\t\tstart: nep.start && nep.start.bind(nep),\n\t};\n}\n","/**\n * `serialize-error` package wrapped as a single file for compatibility\n * with both CJS and ESM.\n *\n * @see https://github.com/sindresorhus/serialize-error\n */\nconst list = [\n\t// Native ES errors https://262.ecma-international.org/12.0/#sec-well-known-intrinsic-objects\n\tError,\n\tEvalError,\n\tRangeError,\n\tReferenceError,\n\tSyntaxError,\n\tTypeError,\n\tURIError,\n\tAggregateError,\n\n\t// Built-in errors\n\tglobalThis.DOMException,\n\n\t// Node-specific errors\n\t// https://nodejs.org/api/errors.html\n\t(globalThis as any).AssertionError,\n\t(globalThis as any).SystemError,\n]\n\t// Non-native Errors are used with `globalThis` because they might be missing. This filter drops\n\t// them when undefined.\n\t.filter(Boolean)\n\t.map((constructor) => [constructor.name, constructor]);\n\nexport type ErrorObject = {\n\tname?: string;\n\tmessage?: string;\n\tstack?: string;\n\tcause?: unknown;\n\tcode?: string;\n} & Record<string, unknown>;\n\nexport const errorConstructors = new Map(list as any);\n\nexport function addKnownErrorConstructor(constructor: any) {\n\tconst { name } = constructor;\n\tif (errorConstructors.has(name)) {\n\t\tthrow new Error(`The error constructor \"${name}\" is already known.`);\n\t}\n\n\ttry {\n\t\t// eslint-disable-next-line no-new -- It just needs to be verified\n\t\tnew constructor();\n\t} catch (error) {\n\t\tthrow new Error(`The error constructor \"${name}\" is not compatible`, {\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\terrorConstructors.set(name, constructor);\n}\n\nexport class NonError extends Error {\n\toverride name = 'NonError';\n\n\tconstructor(message: any) {\n\t\tsuper(NonError._prepareSuperMessage(message));\n\t}\n\n\tstatic _prepareSuperMessage(message: any) {\n\t\ttry {\n\t\t\treturn JSON.stringify(message);\n\t\t} catch {\n\t\t\treturn String(message);\n\t\t}\n\t}\n}\n\nconst errorProperties = [\n\t{\n\t\tproperty: 'name',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'message',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'stack',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'code',\n\t\tenumerable: true,\n\t},\n\t{\n\t\tproperty: 'cause',\n\t\tenumerable: false,\n\t},\n\t{\n\t\tproperty: 'errors',\n\t\tenumerable: false,\n\t},\n];\n\nconst toJsonWasCalled = new WeakSet();\n\nconst toJSON = (from: any) => {\n\ttoJsonWasCalled.add(from);\n\tconst json = from.toJSON();\n\ttoJsonWasCalled.delete(from);\n\treturn json;\n};\n\nconst newError = (name: any) => {\n\tconst ErrorConstructor = errorConstructors.get(name) ?? (Error as any);\n\treturn ErrorConstructor === AggregateError\n\t\t? new ErrorConstructor([])\n\t\t: new ErrorConstructor();\n};\n\n// eslint-disable-next-line complexity\nconst destroyCircular = ({\n\tfrom,\n\tseen,\n\tto,\n\tforceEnumerable,\n\tmaxDepth,\n\tdepth,\n\tuseToJSON,\n\tserialize,\n}: {\n\tfrom?: any;\n\tseen: any[];\n\tto?: any;\n\tforceEnumerable: boolean;\n\tmaxDepth: number;\n\tdepth: number;\n\tuseToJSON: boolean;\n\tserialize: boolean;\n}) => {\n\tif (!to) {\n\t\tif (Array.isArray(from)) {\n\t\t\tto = [];\n\t\t} else if (!serialize && isErrorLike(from)) {\n\t\t\tto = newError(from.name);\n\t\t} else {\n\t\t\tto = {};\n\t\t}\n\t}\n\n\tseen.push(from);\n\n\tif (depth >= maxDepth) {\n\t\treturn to;\n\t}\n\n\tif (\n\t\tuseToJSON &&\n\t\ttypeof from.toJSON === 'function' &&\n\t\t!toJsonWasCalled.has(from)\n\t) {\n\t\treturn toJSON(from);\n\t}\n\n\tconst continueDestroyCircular = (value: any) =>\n\t\tdestroyCircular({\n\t\t\tfrom: value,\n\t\t\tseen: [...seen],\n\t\t\tforceEnumerable,\n\t\t\tmaxDepth,\n\t\t\tdepth,\n\t\t\tuseToJSON,\n\t\t\tserialize,\n\t\t});\n\n\tfor (const [key, value] of Object.entries(from)) {\n\t\tif (\n\t\t\tvalue &&\n\t\t\tvalue instanceof Uint8Array &&\n\t\t\tvalue.constructor.name === 'Buffer'\n\t\t) {\n\t\t\tto[key] = '[object Buffer]';\n\t\t\tcontinue;\n\t\t}\n\n\t\t// TODO: Use `stream.isReadable()` when targeting Node.js 18.\n\t\tif (\n\t\t\tvalue !== null &&\n\t\t\ttypeof value === 'object' &&\n\t\t\ttypeof (value as any).pipe === 'function'\n\t\t) {\n\t\t\tto[key] = '[object Stream]';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (typeof value === 'function') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!value || typeof value !== 'object') {\n\t\t\t// Gracefully handle non-configurable errors like `DOMException`.\n\t\t\ttry {\n\t\t\t\tto[key] = value;\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!seen.includes(from[key])) {\n\t\t\tdepth++;\n\t\t\tto[key] = continueDestroyCircular(from[key]);\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tto[key] = '[Circular]';\n\t}\n\n\tif (serialize || to instanceof Error) {\n\t\tfor (const { property, enumerable } of errorProperties) {\n\t\t\tif (from[property] !== undefined && from[property] !== null) {\n\t\t\t\tObject.defineProperty(to, property, {\n\t\t\t\t\tvalue:\n\t\t\t\t\t\tisErrorLike(from[property]) ||\n\t\t\t\t\t\tArray.isArray(from[property])\n\t\t\t\t\t\t\t? continueDestroyCircular(from[property])\n\t\t\t\t\t\t\t: from[property],\n\t\t\t\t\tenumerable: forceEnumerable ? true : enumerable,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\nexport function serializeError(value: any, options: any = {}) {\n\tconst { maxDepth = Number.POSITIVE_INFINITY, useToJSON = true } = options;\n\n\tif (typeof value === 'object' && value !== null) {\n\t\treturn destroyCircular({\n\t\t\tfrom: value,\n\t\t\tseen: [],\n\t\t\tforceEnumerable: true,\n\t\t\tmaxDepth,\n\t\t\tdepth: 0,\n\t\t\tuseToJSON,\n\t\t\tserialize: true,\n\t\t});\n\t}\n\n\t// People sometimes throw things besides Error objects…\n\tif (typeof value === 'function') {\n\t\t// `JSON.stringify()` discards functions. We do too, unless a function is thrown directly.\n\t\t// We intentionally use `||` because `.name` is an empty string for anonymous functions.\n\t\treturn `[Function: ${value.name || 'anonymous'}]`;\n\t}\n\n\treturn value;\n}\n\nexport function deserializeError(value: any, options: any = {}) {\n\tconst { maxDepth = Number.POSITIVE_INFINITY } = options;\n\n\tif (value instanceof Error) {\n\t\treturn value;\n\t}\n\n\tif (isMinimumViableSerializedError(value)) {\n\t\treturn destroyCircular({\n\t\t\tfrom: value,\n\t\t\tseen: [],\n\t\t\tto: newError(value.name),\n\t\t\tmaxDepth,\n\t\t\tdepth: 0,\n\t\t\tserialize: false,\n\t\t} as any);\n\t}\n\n\treturn new NonError(value);\n}\n\nexport function isErrorLike(value: any) {\n\treturn (\n\t\tBoolean(value) &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.name === 'string' &&\n\t\ttypeof value.message === 'string' &&\n\t\ttypeof value.stack === 'string'\n\t);\n}\n\n// Used as a weak check for immediately-passed objects, whereas `isErrorLike` is used for nested\n// values to avoid bad detection\nfunction isMinimumViableSerializedError(value: any) {\n\t// @ts-ignore\n\treturn (\n\t\tBoolean(value) &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof value.message === 'string' &&\n\t\t!Array.isArray(value)\n\t);\n}\n","import type { PHPResponseData } from './php-response';\nimport { PHPResponse, StreamedPHPResponse } from './php-response';\nimport * as Comlink from './comlink-sync';\nimport {\n\tNodeSABSyncReceiveMessageTransport,\n\tnodeEndpoint,\n\ttype NodeEndpoint,\n\ttype Remote,\n\ttype Endpoint,\n\ttype IsomorphicMessagePort,\n} from './comlink-sync';\nimport * as ErrorSerializer from './serialize-error';\n\nexport type WithAPIState = {\n\t/**\n\t * Resolves to true when the remote API is ready for\n\t * Comlink communication, but not necessarily fully initialized yet.\n\t */\n\tisConnected: () => Promise<void>;\n\t/**\n\t * Resolves to true when the remote API is declares it's\n\t * fully loaded and ready to be used.\n\t */\n\tisReady: () => Promise<void>;\n};\nexport type RemoteAPI<T> = Remote<T> & WithAPIState;\n\nexport async function consumeAPISync<APIType>(\n\tremote: IsomorphicMessagePort\n): Promise<APIType> {\n\tsetupTransferHandlers();\n\tconst transport = await NodeSABSyncReceiveMessageTransport.create();\n\treturn Comlink.wrapSync<APIType>(remote, transport);\n}\n\nexport function consumeAPI<APIType>(\n\tremote: Worker | Window | NodeEndpoint,\n\tcontext: undefined | EventTarget = undefined\n): RemoteAPI<APIType> {\n\tsetupTransferHandlers();\n\n\tlet endpoint;\n\tconst appearsToBeNodeEnvironment = import.meta.url.startsWith('file://');\n\tif (appearsToBeNodeEnvironment) {\n\t\tendpoint = nodeEndpoint(remote as NodeEndpoint);\n\t} else {\n\t\tendpoint =\n\t\t\tremote instanceof Worker\n\t\t\t\t? remote\n\t\t\t\t: Comlink.windowEndpoint(remote as Window, context);\n\t}\n\n\t/**\n\t * This shouldn't be necessary, but Comlink doesn't seem to\n\t * handle the initial isConnected() call correctly unless it's\n\t * explicitly provided here. This is especially weird\n\t * since the only thing this proxy does is to call the\n\t * isConnected() method on the remote API.\n\t *\n\t * @TODO: Remove this workaround.\n\t */\n\tconst api = Comlink.wrap<APIType & WithAPIState>(endpoint);\n\tconst methods = proxyClone(api);\n\treturn new Proxy(methods, {\n\t\tget: (target, prop) => {\n\t\t\tif (prop === 'isConnected') {\n\t\t\t\treturn async () => {\n\t\t\t\t\t// Keep retrying until the remote API confirms it's connected.\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait runWithTimeout(api.isConnected(), 200);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Timeout exceeded, try again. We can't just use a single\n\t\t\t\t\t\t\t// `runWithTimeout` call because it won't reach the remote API\n\t\t\t\t\t\t\t// if it's not connected yet. Instead, we need to keep retrying\n\t\t\t\t\t\t\t// until the remote API is connected and registers a handler\n\t\t\t\t\t\t\t// for the `isConnected` method.\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\treturn (api as any)[prop];\n\t\t},\n\t}) as unknown as RemoteAPI<APIType>;\n}\n\nasync function runWithTimeout<T>(\n\tpromise: Promise<T>,\n\ttimeout: number\n): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tsetTimeout(reject, timeout);\n\t\tpromise.then(resolve);\n\t});\n}\n\nexport type PublicAPI<Methods, PipedAPI = unknown> = RemoteAPI<\n\tMethods & PipedAPI\n>;\n\nexport function exposeAPI<Methods, PipedAPI>(\n\tapiMethods?: Methods,\n\tpipedApi?: PipedAPI,\n\ttargetWorker?: NodeEndpoint\n): [() => void, (e: Error) => void, PublicAPI<Methods, PipedAPI>] {\n\tconst { setReady, setFailed, exposedApi } = prepareForExpose(\n\t\tapiMethods,\n\t\tpipedApi\n\t);\n\tlet endpoint: Endpoint | undefined;\n\tif (targetWorker) {\n\t\t// NOTE: If there are other target types, we could expand this later,\n\t\t// but for now, we only need support for NodeEndpoints.\n\t\tendpoint = nodeEndpoint(targetWorker);\n\t} else {\n\t\tendpoint =\n\t\t\ttypeof window !== 'undefined'\n\t\t\t\t? Comlink.windowEndpoint(self.parent)\n\t\t\t\t: undefined;\n\t}\n\tComlink.expose(exposedApi, endpoint);\n\treturn [setReady, setFailed, exposedApi as PublicAPI<Methods, PipedAPI>];\n}\n\nexport async function exposeSyncAPI<Methods>(\n\tapiMethods: Methods,\n\tport: IsomorphicMessagePort\n): Promise<[() => void, (e: Error) => void, Methods]> {\n\tconst { setReady, setFailed, exposedApi } = prepareForExpose(apiMethods);\n\tconst transport = await NodeSABSyncReceiveMessageTransport.create();\n\tconst endpoint = nodeEndpoint(port as any);\n\tComlink.exposeSync(exposedApi, endpoint, transport);\n\treturn [setReady, setFailed, exposedApi as Methods];\n}\n\nfunction prepareForExpose<Methods, PipedAPI>(\n\tapiMethods?: Methods,\n\tpipedApi?: PipedAPI\n) {\n\tsetupTransferHandlers();\n\n\tconst connected = Promise.resolve();\n\n\tlet setReady: any;\n\tlet setFailed: any;\n\tconst ready = new Promise((resolve, reject) => {\n\t\tsetReady = resolve;\n\t\tsetFailed = reject;\n\t});\n\n\tconst methods = proxyClone(apiMethods);\n\tconst exposedApi = new Proxy(methods, {\n\t\tget: (target, prop) => {\n\t\t\tif (prop === 'isConnected') {\n\t\t\t\treturn () => connected;\n\t\t\t} else if (prop === 'isReady') {\n\t\t\t\treturn () => ready;\n\t\t\t} else if (prop in target) {\n\t\t\t\treturn target[prop];\n\t\t\t}\n\t\t\treturn (pipedApi as any)?.[prop];\n\t\t},\n\t}) as unknown as PublicAPI<Methods, PipedAPI>;\n\n\treturn { setReady, setFailed, exposedApi };\n}\n\nlet isTransferHandlersSetup = false;\nfunction setupTransferHandlers() {\n\tif (isTransferHandlersSetup) {\n\t\treturn;\n\t}\n\tisTransferHandlersSetup = true;\n\tComlink.transferHandlers.set('EVENT', {\n\t\tcanHandle: (obj): obj is CustomEvent => obj instanceof CustomEvent,\n\t\tserialize: (ev: CustomEvent) => {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tdetail: ev.detail,\n\t\t\t\t},\n\t\t\t\t[],\n\t\t\t];\n\t\t},\n\t\tdeserialize: (obj) => obj,\n\t});\n\tComlink.transferHandlers.set('FUNCTION', {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n\t\tcanHandle: (obj: unknown): obj is Function => typeof obj === 'function',\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n\t\tserialize(obj: Function) {\n\t\t\tconst { port1, port2 } = new MessageChannel();\n\t\t\tComlink.expose(obj, port1);\n\t\t\treturn [port2, [port2]];\n\t\t},\n\t\tdeserialize(port: any) {\n\t\t\tport.start();\n\t\t\treturn Comlink.wrap(port);\n\t\t},\n\t});\n\tComlink.transferHandlers.set('MESSAGE_PORT', {\n\t\tcanHandle: (obj: unknown): obj is MessagePort =>\n\t\t\tobj instanceof MessagePort,\n\t\tserialize(port: MessagePort): [MessagePort, Transferable[]] {\n\t\t\treturn [port, [port]];\n\t\t},\n\t\tdeserialize(port: MessagePort): MessagePort {\n\t\t\treturn port;\n\t\t},\n\t});\n\tComlink.transferHandlers.set('PHPResponse', {\n\t\tcanHandle: (obj: unknown): obj is PHPResponseData =>\n\t\t\ttypeof obj === 'object' &&\n\t\t\tobj !== null &&\n\t\t\t'headers' in obj &&\n\t\t\t'bytes' in obj &&\n\t\t\t'errors' in obj &&\n\t\t\t'exitCode' in obj &&\n\t\t\t'httpStatusCode' in obj,\n\t\tserialize(obj: PHPResponse): [PHPResponseData, Transferable[]] {\n\t\t\tconst data = obj.toRawData();\n\t\t\t// Transfer the ArrayBuffer instead of cloning it to avoid\n\t\t\t// \"could not be cloned\" errors when the buffer is detached\n\t\t\tconst transferables: Transferable[] = [];\n\t\t\tif (data.bytes.buffer.byteLength > 0) {\n\t\t\t\ttransferables.push(data.bytes.buffer);\n\t\t\t}\n\t\t\treturn [data, transferables];\n\t\t},\n\t\tdeserialize(responseData: PHPResponseData): PHPResponse {\n\t\t\treturn PHPResponse.fromRawData(responseData);\n\t\t},\n\t});\n\t// Augment Comlink's throw handler to include Error the response and source\n\t// information in the serialized error object. BasePHP may throw\n\t// PHPExecutionFailureError which includes those information and we'll want to\n\t// display them for the user.\n\tconst throwHandler = Comlink.transferHandlers.get('throw')!;\n\tconst originalSerialize = throwHandler?.serialize;\n\tthrowHandler.serialize = ({ value }: any) => {\n\t\tconst serialized = originalSerialize({ value }) as any;\n\t\tif (value.response) {\n\t\t\tserialized[0].value.response = value.response;\n\t\t}\n\t\tif (value.source) {\n\t\t\tserialized[0].value.source = value.source;\n\t\t}\n\t\treturn serialized;\n\t};\n\n\tComlink.transferHandlers.set('StreamedPHPResponse', {\n\t\tcanHandle: (obj: unknown): obj is StreamedPHPResponse =>\n\t\t\tobj instanceof StreamedPHPResponse,\n\t\tserialize(obj: StreamedPHPResponse): [any, Transferable[]] {\n\t\t\tconst supportsStreams = supportsTransferableStreams();\n\t\t\tconst exitCodePort = promiseToPort(obj.exitCode);\n\t\t\tif (supportsStreams) {\n\t\t\t\tconst payload = {\n\t\t\t\t\t__type: 'StreamedPHPResponse',\n\t\t\t\t\theaders: (obj as any)['headersStream'],\n\t\t\t\t\tstdout: obj.stdout,\n\t\t\t\t\tstderr: obj.stderr,\n\t\t\t\t\texitCodePort,\n\t\t\t\t};\n\t\t\t\treturn [payload, [exitCodePort]];\n\t\t\t}\n\t\t\t// Fallback: bridge streams via MessagePorts\n\t\t\tconst headersPort = streamToPort((obj as any)['headersStream']);\n\t\t\tconst stdoutPort = streamToPort(obj.stdout);\n\t\t\tconst stderrPort = streamToPort(obj.stderr);\n\t\t\tconst payload = {\n\t\t\t\t__type: 'StreamedPHPResponse',\n\t\t\t\theadersPort,\n\t\t\t\tstdoutPort,\n\t\t\t\tstderrPort,\n\t\t\t\texitCodePort,\n\t\t\t};\n\t\t\treturn [\n\t\t\t\tpayload,\n\t\t\t\t[headersPort, stdoutPort, stderrPort, exitCodePort],\n\t\t\t];\n\t\t},\n\t\tdeserialize(data: any): StreamedPHPResponse {\n\t\t\tif (data.headers && data.stdout && data.stderr) {\n\t\t\t\tconst exitCode = portToPromise(\n\t\t\t\t\tdata.exitCodePort as MessagePort\n\t\t\t\t);\n\t\t\t\treturn new StreamedPHPResponse(\n\t\t\t\t\tdata.headers as ReadableStream<Uint8Array>,\n\t\t\t\t\tdata.stdout as ReadableStream<Uint8Array>,\n\t\t\t\t\tdata.stderr as ReadableStream<Uint8Array>,\n\t\t\t\t\texitCode\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst headers = portToStream(data.headersPort as MessagePort);\n\t\t\tconst stdout = portToStream(data.stdoutPort as MessagePort);\n\t\t\tconst stderr = portToStream(data.stderrPort as MessagePort);\n\t\t\tconst exitCode = portToPromise(data.exitCodePort as MessagePort);\n\t\t\treturn new StreamedPHPResponse(headers, stdout, stderr, exitCode);\n\t\t},\n\t});\n}\n\n// Utilities for transferring ReadableStreams and Promises via MessagePorts:\n\n/**\n * Safari does not support transferable streams, so we need to fallback to\n * MessagePorts.\n * Feature-detects whether this runtime supports transferring ReadableStreams\n * directly through postMessage (aka \"transferable streams\"). When false,\n * we must fall back to port-bridged streaming.\n */\nfunction supportsTransferableStreams(): boolean {\n\ttry {\n\t\tif (typeof ReadableStream === 'undefined') return false;\n\t\tconst { port1 } = new MessageChannel();\n\t\tconst rs = new ReadableStream();\n\t\tport1.postMessage(rs as any);\n\t\ttry {\n\t\t\tport1.close();\n\t\t} catch (_e) {\n\t\t\tvoid _e;\n\t\t}\n\t\treturn true;\n\t} catch (_e) {\n\t\tvoid _e;\n\t\treturn false;\n\t}\n}\n\n/**\n * Bridges a ReadableStream to a MessagePort by reading chunks and posting\n * messages to the port. Used as a fallback when transferable streams are not\n * supported (e.g., Safari).\n *\n * Protocol of the returned MessagePort:\n *\n * { t: 'chunk', b: ArrayBuffer } – next binary chunk\n * { t: 'close' } – end of stream\n * { t: 'error', m: string } – terminal error\n */\nfunction streamToPort(stream: ReadableStream<Uint8Array>): MessagePort {\n\tconst { port1, port2 } = new MessageChannel();\n\t(async () => {\n\t\tconst reader = stream.getReader();\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tport1.postMessage({ t: 'close' });\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Ignore error\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tport1.close();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Ignore error\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (value) {\n\t\t\t\t\t// Ensure we transfer an owned buffer\n\t\t\t\t\tconst owned =\n\t\t\t\t\t\tvalue.byteOffset === 0 &&\n\t\t\t\t\t\tvalue.byteLength === value.buffer.byteLength\n\t\t\t\t\t\t\t? value\n\t\t\t\t\t\t\t: value.slice();\n\t\t\t\t\tconst buf = owned.buffer;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tport1.postMessage({ t: 'chunk', b: buf }, [\n\t\t\t\t\t\t\tbuf as unknown as Transferable,\n\t\t\t\t\t\t]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tport1.postMessage({\n\t\t\t\t\t\t\tt: 'chunk',\n\t\t\t\t\t\t\tb: owned.buffer.slice(0),\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} catch (e: any) {\n\t\t\ttry {\n\t\t\t\tport1.postMessage({ t: 'error', m: e?.message || String(e) });\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tport1.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t}\n\t})();\n\treturn port2;\n}\n\n/**\n * Reconstructs a ReadableStream from a MessagePort using the inverse of the\n * streamToPort protocol. Each message enqueues data, closes, or errors.\n */\nfunction portToStream(port: MessagePort): ReadableStream<Uint8Array> {\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tconst onMessage = (ev: MessageEvent) => {\n\t\t\t\tconst data: any = (ev as any).data;\n\t\t\t\tif (!data) return;\n\t\t\t\tswitch (data.t) {\n\t\t\t\t\tcase 'chunk':\n\t\t\t\t\t\tcontroller.enqueue(new Uint8Array(data.b));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'close':\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'error':\n\t\t\t\t\t\tcontroller.error(new Error(data.m || 'Stream error'));\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst cleanup = () => {\n\t\t\t\ttry {\n\t\t\t\t\tport.removeEventListener?.('message', onMessage as any);\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tport.onmessage = null;\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tport.close();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore error\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (port.addEventListener) {\n\t\t\t\tport.addEventListener('message', onMessage as any);\n\t\t\t} else if ((port as any).on) {\n\t\t\t\t(port as any).on('message', (data: any) =>\n\t\t\t\t\tonMessage({ data } as any)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tport.onmessage = onMessage as any;\n\t\t\t}\n\t\t\tif (typeof port.start === 'function') {\n\t\t\t\tport.start();\n\t\t\t}\n\t\t},\n\t\tcancel() {\n\t\t\ttry {\n\t\t\t\tport.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Bridges a Promise to a MessagePort so it can be delivered across threads.\n *\n * Protocol of the returned MessagePort:\n *\n * { t: 'resolve', v: any } – promise resolved with value v\n * { t: 'reject', m: str } – promise rejected with message m\n */\nfunction promiseToPort(promise: Promise<any>): MessagePort {\n\tconst { port1, port2 } = new MessageChannel();\n\tpromise\n\t\t.then((value) => {\n\t\t\ttry {\n\t\t\t\tport1.postMessage({ t: 'resolve', v: value });\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t})\n\t\t.catch((err) => {\n\t\t\ttry {\n\t\t\t\tport1.postMessage({\n\t\t\t\t\tt: 'reject',\n\t\t\t\t\tm: (err as any)?.message || String(err),\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t})\n\t\t.finally(() => {\n\t\t\ttry {\n\t\t\t\tport1.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t});\n\treturn port2;\n}\n\n/**\n * Reconstructs a Promise from a MessagePort using the inverse of\n * promiseToPort. Resolves or rejects when the corresponding message arrives.\n */\nfunction portToPromise(port: MessagePort): Promise<any> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst onMessage = (ev: MessageEvent) => {\n\t\t\tconst data: any = (ev as any).data;\n\t\t\tif (!data) return;\n\t\t\tif (data.t === 'resolve') {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(data.v);\n\t\t\t} else if (data.t === 'reject') {\n\t\t\t\tcleanup();\n\t\t\t\treject(new Error(data.m || ''));\n\t\t\t}\n\t\t};\n\t\tconst cleanup = () => {\n\t\t\ttry {\n\t\t\t\tport.removeEventListener?.('message', onMessage as any);\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tport.onmessage = null;\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tport.close();\n\t\t\t} catch {\n\t\t\t\t// Ignore error\n\t\t\t}\n\t\t};\n\t\tif (port.addEventListener) {\n\t\t\tport.addEventListener('message', onMessage as any);\n\t\t} else if ((port as any).on) {\n\t\t\t(port as any).on('message', (data: any) =>\n\t\t\t\tonMessage({ data } as any)\n\t\t\t);\n\t\t} else {\n\t\t\tport.onmessage = onMessage as any;\n\t\t}\n\t\tif (typeof port.start === 'function') {\n\t\t\tport.start();\n\t\t}\n\t});\n}\n\n// Augment Comlink's throw handler to include all the information carried by\n// the thrown object, including the cause, additional properties, etc.\ninterface UnserializedError {\n\tvalue: unknown;\n}\ntype SerializedError =\n\t| { isError: true; value: ErrorSerializer.ErrorObject }\n\t| { isError: false; value: unknown };\n\nconst throwTransferHandler = Comlink.transferHandlers.get(\n\t'throw'\n) as Comlink.TransferHandler<UnserializedError, SerializedError>;\n\nconst throwTransferHandlerCustom: Comlink.TransferHandler<\n\tUnserializedError,\n\tSerializedError\n> = {\n\tcanHandle: throwTransferHandler.canHandle,\n\tserialize: ({ value }) => {\n\t\tlet serialized: SerializedError;\n\t\tif (value instanceof Error) {\n\t\t\tserialized = {\n\t\t\t\tisError: true,\n\t\t\t\tvalue: ErrorSerializer.serializeError(value),\n\t\t\t};\n\t\t\t// The error class name is not serialized by serialize-error, let's add it manually.\n\t\t\tserialized.value['originalErrorClassName'] = value.constructor.name;\n\t\t} else {\n\t\t\tserialized = { isError: false, value };\n\t\t}\n\t\treturn [serialized, []];\n\t},\n\tdeserialize: (serialized) => {\n\t\tif (serialized.isError) {\n\t\t\tconst error = ErrorSerializer.deserializeError(serialized.value);\n\t\t\t/**\n\t\t\t * The original error from the web worker does not include any call\n\t\t\t * stack from the Playground web app. Let's include that information\n\t\t\t * in the error chain.\n\t\t\t *\n\t\t\t * We'll place it at the bottom of the error chain. This way the API\n\t\t\t * consumer gets the original error object and not an opaque\n\t\t\t * \"Comlink method call failed\" error, but they can still inspect\n\t\t\t * it further to see the full call stack.\n\t\t\t */\n\t\t\tconst additionalCallStack = new Error('Comlink method call failed');\n\t\t\tlet deepestError = error;\n\t\t\twhile (deepestError.cause) {\n\t\t\t\tdeepestError = deepestError.cause;\n\t\t\t}\n\t\t\tdeepestError.cause = additionalCallStack;\n\t\t\tthrow error;\n\t\t}\n\t\tthrow serialized.value;\n\t},\n};\n\nComlink.transferHandlers.set('throw', throwTransferHandlerCustom);\n\nfunction proxyClone(object: any): any {\n\treturn new Proxy(object, {\n\t\tget(target, prop) {\n\t\t\tswitch (typeof target[prop]) {\n\t\t\t\tcase 'function':\n\t\t\t\t\treturn (...args: any[]) => target[prop](...args);\n\t\t\t\tcase 'object':\n\t\t\t\t\tif (target[prop] === null) {\n\t\t\t\t\t\treturn target[prop];\n\t\t\t\t\t}\n\t\t\t\t\treturn proxyClone(target[prop]);\n\t\t\t\tcase 'undefined':\n\t\t\t\tcase 'number':\n\t\t\t\tcase 'string':\n\t\t\t\t\treturn target[prop];\n\t\t\t\tdefault:\n\t\t\t\t\treturn Comlink.proxy(target[prop]);\n\t\t\t}\n\t\t},\n\t});\n}\n"],"names":["errno","message","options","e","messagePrefix","value","args","errmsg","path","formattedPrefix","FS","data","fromPath","toPath","fromMount","toMount","dirname","mountPoint","file","filePath","joinPaths","files","name","prepend","logger","target","link","fromNode","filenames","filename","requestHandler","monitor","__privateAdd","_eventListeners","__privateSet","php","internalUrl","callback","_a","request","reap","argv","response","error","newName","listener","l","key","eventType","__privateGet","event","listeners","returnData","phpLoaderModule","phpModuleArgs","phpReady","resolvePHP","rejectPHP","PHPRuntime","reason","id","code","dangerouslyKeepTheRuntimeInTheMap","runtime","methods","promise","resolve","reject","headers","stdout","stderr","exitCode","statusCode","result","bytes","headersStream","headersText","headersData","line","colonIndex","headerName","headerValue","stream","reader","text","done","chunks","totalLength","acc","chunk","offset","httpStatusCode","body","errors","streamedResponse","type","original","clearMessage","crypticError","asyncifyStack","betterMessage","uniqueFunctions","lastError","fn","stack","names","parts","isWasm","source","PHPRuntimeId","_PHP_instances","_sapiName","_phpWasmInitCalled","_wasmErrorsTarget","_messageListeners","_mounts","_rotationOptions","Semaphore","createSpawnHandler","runtimeId","opcacheConfig","mode","syncResponse","release","heapBodyPointer","streamedResponsePromise","__privateMethod","executeWithErrorHandling_fn","setRelativeRequestUri_fn","setRequestMethod_fn","requestHeaders","host","port","inferPortFromHostAndProtocol_fn","setRequestHost_fn","setRequestPort_fn","setRequestHeaders_fn","setRequestBody_fn","setScriptPath_fn","$_SERVER","prepareServerEntries_fn","setServerGlobalEntry_fn","env","setEnv_fn","cleanup","consts","oldFS","oldRootLevelPaths","oldSpawnProcess","oldCWD","mountHandlersToReapplyInOrder","vfsPath","mount","mountsToUnmountInReverseOrder","newFs","mountHandler","virtualFSPath","unmountCallback","mountObject","basename","arg","process","stderrStream","stdoutStream","controller","shouldSkip","defaults","HTTP_prefix","uri","queryString","protocol","method","size","contentLength","executionFn","emscriptenModule","streamsClosed","headersClosed","closeHeadersStream","errorListener","exitCodePromise","_","normalized","oldNode","controllerResolve","controllerPromise","fs","entries","ini","parse","stringify","phpIniValues","iniBefore","current","isFirst","hasHeaders","setCookie","equalsIndex","cookiesArray","buffer","root","relativePaths","pathPrefix","exceptPaths","normalizePath","currentParent","absPath","StreamedFile","limit","considerPrimary","acquiredPHP","factoryArgs","spawned","pop","instance","rejection","AcquireTimeoutError","url","prefix","boundary","contentType","textEncoder","length","part","fileBuffer","config","_PHPRequestHandler_instances","_DOCROOT","_PROTOCOL","_HOSTNAME","_PORT","_HOST","_PATHNAME","_ABSOLUTE_URL","_cookieStore","documentRoot","absoluteUrl","rewriteRules","getFileNotFoundAction","setChroot","info","isNonStandardPort","isAbsolute","originalRequestUrl","rewrittenRequestUrl","applyRewriteRules_fn","primaryPhp","fsPath","possibleIndexFile","possibleIndexPath","pathToTry","resolvedPathToTry","fileNotFoundAction","spawnPHPAndDispatchRequest_fn","serveStaticFile_fn","resolvedScriptPath","siteRelativePath","rewrittenRequestPath","arrayBuffer","scriptPath","spawnedPHP","dispatchToPHP_fn","preferredMethod","executionError","extension","rules","rule","recreateRuntime","maxRequests","newFiles","rmRoot","relativePath","content","sourceOfTruth","replica","paths","__private__symbol","fsResult","getPHPInstance","processApi","splitShellCommand","binaryName","cwd","obj","ep","transport","allowedOrigins","_t","prop","res","v","xfer","_thisArg","rawArgs","argList","wire","m","ev","notifyBuffer","view","msg","transferables","latch","val","port1","port2","throwTransferHandler","serialized","origin","allowedOrigin","afterResponseSent","argumentList","returnValue","parent","rawValue","wireValue","endpoint","pendingListeners","resolver","isReleased","newCount","proxy","isProxyReleased","_target","r","p","rawArgumentList","last","arr","processed","transfers","w","context","targetOrigin","handler","serializedValue","nep","eh","constructor","from","json","ErrorConstructor","seen","to","forceEnumerable","maxDepth","depth","useToJSON","serialize","continueDestroyCircular","property","enumerable","remote","Comlink.wrapSync","Comlink.windowEndpoint","api","Comlink.wrap","timeout","apiMethods","pipedApi","targetWorker","setReady","setFailed","exposedApi","Comlink.expose","Comlink.exposeSync","connected","ready","Comlink.transferHandlers","responseData","throwHandler","originalSerialize","supportsStreams","exitCodePort","headersPort","stdoutPort","stderrPort","rs","owned","buf","onMessage","err","ErrorSerializer.serializeError","ErrorSerializer.deserializeError","additionalCallStack","deepestError","object","Comlink.proxy"],"mappings":"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"}
|