@php-wasm/fs-journal 0.6.15 → 0.7.0

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.
Files changed (3) hide show
  1. package/index.cjs +8 -8
  2. package/index.js +367 -281
  3. package/package.json +2 -2
package/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Y=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var l=(e,t,r)=>(Y(e,t,"read from private field"),r?r.call(e):t.get(e)),u=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},h=(e,t,r,s)=>(Y(e,t,"write to private field"),s?s.call(e,r):t.set(e,r),r);var f=(e,t,r)=>(Y(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const currentJsRuntime=function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}();if(currentJsRuntime==="NODE"){let e=function(r){return new Promise(function(s,n){r.onload=r.onerror=function(i){r.onload=r.onerror=null,i.type==="load"?s(r.result):n(new Error("Failed to read the blob/file"))}})},t=function(){const r=new Uint8Array([1,2,3,4]),n=new File([r],"test").stream();try{return n.getReader({mode:"byob"}),!0}catch{return!1}};if(typeof File>"u"){class r extends Blob{constructor(n,i,o){super(n);let a;o!=null&&o.lastModified&&(a=new Date),(!a||isNaN(a.getFullYear()))&&(a=new Date),this.lastModifiedDate=a,this.lastModified=a.getMilliseconds(),this.name=i||""}}global.File=r}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const s=new FileReader;return s.readAsArrayBuffer(this),e(s)}),typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const s=new FileReader;return s.readAsText(this),e(s)}),(typeof Blob.prototype.stream>"u"||!t())&&(Blob.prototype.stream=function(){let r=0;const s=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(n){const i=n.byobRequest.view,a=await s.slice(r,r+i.byteLength).arrayBuffer(),c=new Uint8Array(a);new Uint8Array(i.buffer).set(c);const d=c.byteLength;n.byobRequest.respond(d),r+=d,r>=s.size&&n.close()}})})}if(currentJsRuntime==="NODE"&&typeof CustomEvent>"u"){class e extends Event{constructor(r,s={}){super(r,s),this.detail=s.detail}initCustomEvent(){}}globalThis.CustomEvent=e}const kError=Symbol("error"),kMessage=Symbol("message");class ErrorEvent2 extends Event{constructor(t,r={}){super(t),this[kError]=r.error===void 0?null:r.error,this[kMessage]=r.message===void 0?"":r.message}get error(){return this[kError]}get message(){return this[kMessage]}}Object.defineProperty(ErrorEvent2.prototype,"error",{enumerable:!0});Object.defineProperty(ErrorEvent2.prototype,"message",{enumerable:!0});const ErrorEvent=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:ErrorEvent2;function isExitCodeZero(e){return e instanceof Error?"exitCode"in e&&(e==null?void 0:e.exitCode)===0||(e==null?void 0:e.name)==="ExitStatus"&&"status"in e&&e.status===0:!1}class UnhandledRejectionsTarget extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(t,r){++this.listenersCount,super.addEventListener(t,r)}removeEventListener(t,r){--this.listenersCount,super.removeEventListener(t,r)}hasListeners(){return this.listenersCount>0}}function improveWASMErrorReporting(e){e.asm={...e.asm};const t=new UnhandledRejectionsTarget;for(const r in e.asm)if(typeof e.asm[r]=="function"){const s=e.asm[r];e.asm[r]=function(...n){var i;try{return s(...n)}catch(o){if(!(o instanceof Error))throw o;const a=clarifyErrorMessage(o,(i=e.lastAsyncifyStackSource)==null?void 0:i.stack);if(e.lastAsyncifyStackSource&&(o.cause=e.lastAsyncifyStackSource),t.hasListeners()){t.dispatchEvent(new ErrorEvent("error",{error:o,message:a}));return}throw isExitCodeZero(o)||showCriticalErrorBox(a),o}}}return t}let functionsMaybeMissingFromAsyncify=[];function getFunctionsMaybeMissingFromAsyncify(){return functionsMaybeMissingFromAsyncify}function clarifyErrorMessage(e,t){if(e.message==="unreachable"){let r=UNREACHABLE_ERROR;t||(r+=`
1
+ "use strict";var Y=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var l=(e,t,r)=>(Y(e,t,"read from private field"),r?r.call(e):t.get(e)),d=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},p=(e,t,r,s)=>(Y(e,t,"write to private field"),s?s.call(e,r):t.set(e,r),r);var f=(e,t,r)=>(Y(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const currentJsRuntime=function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}();if(currentJsRuntime==="NODE"){let e=function(r){return new Promise(function(s,n){r.onload=r.onerror=function(i){r.onload=r.onerror=null,i.type==="load"?s(r.result):n(new Error("Failed to read the blob/file"))}})},t=function(){const r=new Uint8Array([1,2,3,4]),n=new File([r],"test").stream();try{return n.getReader({mode:"byob"}),!0}catch{return!1}};if(typeof File>"u"){class r extends Blob{constructor(n,i,o){super(n);let a;o!=null&&o.lastModified&&(a=new Date),(!a||isNaN(a.getFullYear()))&&(a=new Date),this.lastModifiedDate=a,this.lastModified=a.getMilliseconds(),this.name=i||""}}global.File=r}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const s=new FileReader;return s.readAsArrayBuffer(this),e(s)}),typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const s=new FileReader;return s.readAsText(this),e(s)}),(typeof Blob.prototype.stream>"u"||!t())&&(Blob.prototype.stream=function(){let r=0;const s=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(n){const i=n.byobRequest.view,a=await s.slice(r,r+i.byteLength).arrayBuffer(),c=new Uint8Array(a);new Uint8Array(i.buffer).set(c);const u=c.byteLength;n.byobRequest.respond(u),r+=u,r>=s.size&&n.close()}})})}if(currentJsRuntime==="NODE"&&typeof CustomEvent>"u"){class e extends Event{constructor(r,s={}){super(r,s),this.detail=s.detail}initCustomEvent(){}}globalThis.CustomEvent=e}const kError=Symbol("error"),kMessage=Symbol("message");class ErrorEvent2 extends Event{constructor(t,r={}){super(t),this[kError]=r.error===void 0?null:r.error,this[kMessage]=r.message===void 0?"":r.message}get error(){return this[kError]}get message(){return this[kMessage]}}Object.defineProperty(ErrorEvent2.prototype,"error",{enumerable:!0});Object.defineProperty(ErrorEvent2.prototype,"message",{enumerable:!0});const ErrorEvent=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:ErrorEvent2;function isExitCodeZero(e){return e instanceof Error?"exitCode"in e&&(e==null?void 0:e.exitCode)===0||(e==null?void 0:e.name)==="ExitStatus"&&"status"in e&&e.status===0:!1}class UnhandledRejectionsTarget extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(t,r){++this.listenersCount,super.addEventListener(t,r)}removeEventListener(t,r){--this.listenersCount,super.removeEventListener(t,r)}hasListeners(){return this.listenersCount>0}}function improveWASMErrorReporting(e){e.asm={...e.asm};const t=new UnhandledRejectionsTarget;for(const r in e.asm)if(typeof e.asm[r]=="function"){const s=e.asm[r];e.asm[r]=function(...n){var i;try{return s(...n)}catch(o){if(!(o instanceof Error))throw o;const a=clarifyErrorMessage(o,(i=e.lastAsyncifyStackSource)==null?void 0:i.stack);if(e.lastAsyncifyStackSource&&(o.cause=e.lastAsyncifyStackSource),t.hasListeners()){t.dispatchEvent(new ErrorEvent("error",{error:o,message:a}));return}throw isExitCodeZero(o)||showCriticalErrorBox(a),o}}}return t}let functionsMaybeMissingFromAsyncify=[];function getFunctionsMaybeMissingFromAsyncify(){return functionsMaybeMissingFromAsyncify}function clarifyErrorMessage(e,t){if(e.message==="unreachable"){let r=UNREACHABLE_ERROR;t||(r+=`
2
2
 
3
3
  This stack trace is lacking. For a better one initialize
4
4
  the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
@@ -32,13 +32,13 @@ CLI option:
32
32
  ${eol}
33
33
  ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
34
34
  `))console.log(`${eol} ${t} `);console.log(`${reset}`)}}function extractPHPFunctionsFromStack(e){try{const t=e.split(`
35
- `).slice(1).map(r=>{const s=r.trim().substring(3).split(" ");return{fn:s.length>=2?s[0]:"<unknown>",isWasm:r.includes("wasm://")}}).filter(({fn:r,isWasm:s})=>s&&!r.startsWith("dynCall_")&&!r.startsWith("invoke_")).map(({fn:r})=>r);return Array.from(new Set(t))}catch{return[]}}class Semaphore{constructor({concurrency:t}){this._running=0,this.concurrency=t,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(t=>this.queue.push(t));else{this._running++;let t=!1;return()=>{t||(t=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(t){const r=await this.acquire();try{return await t()}finally{r()}}}function joinPaths(...e){let t=e.join("/");const r=t[0]==="/",s=t.substring(t.length-1)==="/";return t=normalizePath$1(t),!t&&!r&&(t="."),t&&s&&(t+="/"),t}function basename(e){if(e==="/")return"/";e=normalizePath$1(e);const t=e.lastIndexOf("/");return t===-1?e:e.substr(t+1)}function normalizePath$1(e){const t=e[0]==="/";return e=normalizePathsArray(e.split("/").filter(r=>!!r),!t).join("/"),(t?"/":"")+e.replace(/\/$/,"")}function normalizePathsArray(e,t){let r=0;for(let s=e.length-1;s>=0;s--){const n=e[s];n==="."?e.splice(s,1):n===".."?(e.splice(s,1),r++):r&&(e.splice(s,1),r--)}if(t)for(;r;r--)e.unshift("..");return e}function splitShellCommand(e){let s=0,n="";const i=[];let o="";for(let a=0;a<e.length;a++){const c=e[a];c==="\\"?((e[a+1]==='"'||e[a+1]==="'")&&a++,o+=e[a]):s===0?c==='"'||c==="'"?(s=1,n=c):c.match(/\s/)?(o.trim().length&&i.push(o.trim()),o=c):i.length&&!o?o=i.pop()+c:o+=c:s===1&&(c===n?(s=0,n=""):o+=c)}return o&&i.push(o.trim()),i}function createSpawnHandler(e){return function(t,r=[],s={}){const n=new ChildProcess,i=new ProcessApi(n);return setTimeout(async()=>{let o=[];if(r.length)o=[t,...r];else if(typeof t=="string")o=splitShellCommand(t);else if(Array.isArray(t))o=t;else throw new Error("Invalid command ",t);await e(o,i,s),n.emit("spawn",!0)}),n}}class EventEmitter{constructor(){this.listeners={}}emit(t,r){this.listeners[t]&&this.listeners[t].forEach(function(s){s(r)})}on(t,r){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(r)}}class ProcessApi extends EventEmitter{constructor(t){super(),this.childProcess=t,this.exited=!1,this.stdinData=[],t.on("stdin",r=>{this.stdinData?this.stdinData.push(r.slice()):this.emit("stdin",r)})}stdout(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stdout.emit("data",t)}stdoutEnd(){this.childProcess.stdout.emit("end",{})}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}stderrEnd(){this.childProcess.stderr.emit("end",{})}exit(t){this.exited||(this.exited=!0,this.childProcess.emit("exit",t))}flushStdin(){if(this.stdinData)for(let t=0;t<this.stdinData.length;t++)this.emit("stdin",this.stdinData[t]);this.stdinData=null}}let lastPid=9743;class ChildProcess extends EventEmitter{constructor(t=lastPid++){super(),this.pid=t,this.stdout=new EventEmitter,this.stderr=new EventEmitter;const r=this;this.stdin={write:s=>{r.emit("stdin",s)}}}}ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:t,value:r}=await e.read();if(t)return;yield r}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);class PHPResponse{constructor(t,r,s,n="",i=0){this.httpStatusCode=t,this.headers=r,this.bytes=s,this.exitCode=i,this.errors=n}static fromRawData(t){return new PHPResponse(t.httpStatusCode,t.headers,t.bytes,t.errors,t.exitCode)}toRawData(){return{headers:this.headers,bytes:this.bytes,errors:this.errors,exitCode:this.exitCode,httpStatusCode:this.httpStatusCode}}get json(){return JSON.parse(this.text)}get text(){return new TextDecoder().decode(this.bytes)}}var v,T;class PHPBrowser{constructor(t,r={}){u(this,v,void 0);u(this,T,void 0);this.requestHandler=t,h(this,v,{}),h(this,T,{handleRedirects:!1,maxRedirects:4,...r})}async request(t,r=0){const s=await this.requestHandler.request({...t,headers:{...t.headers,cookie:this.serializeCookies()}});if(s.headers["set-cookie"]&&this.setCookies(s.headers["set-cookie"]),l(this,T).handleRedirects&&s.headers.location&&r<l(this,T).maxRedirects){const n=new URL(s.headers.location[0],this.requestHandler.absoluteUrl);return this.request({url:n.toString(),method:"GET",headers:{}},r+1)}return s}pathToInternalUrl(t){return this.requestHandler.pathToInternalUrl(t)}internalUrlToPath(t){return this.requestHandler.internalUrlToPath(t)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}setCookies(t){for(const r of t)try{if(!r.includes("="))continue;const s=r.indexOf("="),n=r.substring(0,s),i=r.substring(s+1).split(";")[0];l(this,v)[n]=i}catch(s){console.error(s)}}serializeCookies(){const t=[];for(const r in l(this,v))t.push(`${r}=${l(this,v)[r]}`);return t.join("; ")}}v=new WeakMap,T=new WeakMap;const DEFAULT_BASE_URL="http://example.com";function toRelativeUrl(e){return e.toString().substring(e.origin.length)}function removePathPrefix(e,t){return!t||!e.startsWith(t)?e:e.substring(t.length)}function ensurePathPrefix(e,t){return!t||e.startsWith(t)?e:t+e}async function encodeAsMultipart(e){const t=`----${Math.random().toString(36).slice(2)}`,r=`multipart/form-data; boundary=${t}`,s=new TextEncoder,n=[];for(const[c,d]of Object.entries(e))n.push(`--${t}\r
36
- `),n.push(`Content-Disposition: form-data; name="${c}"`),d instanceof File&&n.push(`; filename="${d.name}"`),n.push(`\r
37
- `),d instanceof File&&(n.push("Content-Type: application/octet-stream"),n.push(`\r
35
+ `).slice(1).map(r=>{const s=r.trim().substring(3).split(" ");return{fn:s.length>=2?s[0]:"<unknown>",isWasm:r.includes("wasm://")}}).filter(({fn:r,isWasm:s})=>s&&!r.startsWith("dynCall_")&&!r.startsWith("invoke_")).map(({fn:r})=>r);return Array.from(new Set(t))}catch{return[]}}const SleepFinished=Symbol("SleepFinished");function sleep(e){return new Promise(t=>{setTimeout(()=>t(SleepFinished),e)})}class AcquireTimeoutError extends Error{constructor(){super("Acquiring lock timed out")}}class Semaphore{constructor({concurrency:t,timeout:r}){this._running=0,this.concurrency=t,this.timeout=r,this.queue=[]}get remaining(){return this.concurrency-this.running}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency){const t=new Promise(r=>{this.queue.push(r)});this.timeout!==void 0?await Promise.race([t,sleep(this.timeout)]).then(r=>{if(r===SleepFinished)throw new AcquireTimeoutError}):await t}else{this._running++;let t=!1;return()=>{t||(t=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(t){const r=await this.acquire();try{return await t()}finally{r()}}}function joinPaths(...e){let t=e.join("/");const r=t[0]==="/",s=t.substring(t.length-1)==="/";return t=normalizePath$1(t),!t&&!r&&(t="."),t&&s&&(t+="/"),t}function basename(e){if(e==="/")return"/";e=normalizePath$1(e);const t=e.lastIndexOf("/");return t===-1?e:e.substr(t+1)}function normalizePath$1(e){const t=e[0]==="/";return e=normalizePathsArray(e.split("/").filter(r=>!!r),!t).join("/"),(t?"/":"")+e.replace(/\/$/,"")}function normalizePathsArray(e,t){let r=0;for(let s=e.length-1;s>=0;s--){const n=e[s];n==="."?e.splice(s,1):n===".."?(e.splice(s,1),r++):r&&(e.splice(s,1),r--)}if(t)for(;r;r--)e.unshift("..");return e}function splitShellCommand(e){let s=0,n="";const i=[];let o="";for(let a=0;a<e.length;a++){const c=e[a];c==="\\"?((e[a+1]==='"'||e[a+1]==="'")&&a++,o+=e[a]):s===0?c==='"'||c==="'"?(s=1,n=c):c.match(/\s/)?(o.trim().length&&i.push(o.trim()),o=c):i.length&&!o?o=i.pop()+c:o+=c:s===1&&(c===n?(s=0,n=""):o+=c)}return o&&i.push(o.trim()),i}function createSpawnHandler(e){return function(t,r=[],s={}){const n=new ChildProcess,i=new ProcessApi(n);return setTimeout(async()=>{let o=[];if(r.length)o=[t,...r];else if(typeof t=="string")o=splitShellCommand(t);else if(Array.isArray(t))o=t;else throw new Error("Invalid command ",t);await e(o,i,s),n.emit("spawn",!0)}),n}}class EventEmitter{constructor(){this.listeners={}}emit(t,r){this.listeners[t]&&this.listeners[t].forEach(function(s){s(r)})}on(t,r){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(r)}}class ProcessApi extends EventEmitter{constructor(t){super(),this.childProcess=t,this.exited=!1,this.stdinData=[],t.on("stdin",r=>{this.stdinData?this.stdinData.push(r.slice()):this.emit("stdin",r)})}stdout(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stdout.emit("data",t)}stdoutEnd(){this.childProcess.stdout.emit("end",{})}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}stderrEnd(){this.childProcess.stderr.emit("end",{})}exit(t){this.exited||(this.exited=!0,this.childProcess.emit("exit",t))}flushStdin(){if(this.stdinData)for(let t=0;t<this.stdinData.length;t++)this.emit("stdin",this.stdinData[t]);this.stdinData=null}}let lastPid=9743;class ChildProcess extends EventEmitter{constructor(t=lastPid++){super(),this.pid=t,this.stdout=new EventEmitter,this.stderr=new EventEmitter;const r=this;this.stdin={write:s=>{r.emit("stdin",s)}}}}ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:t,value:r}=await e.read();if(t)return;yield r}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);class PHPResponse{constructor(t,r,s,n="",i=0){this.httpStatusCode=t,this.headers=r,this.bytes=s,this.exitCode=i,this.errors=n}static fromRawData(t){return new PHPResponse(t.httpStatusCode,t.headers,t.bytes,t.errors,t.exitCode)}toRawData(){return{headers:this.headers,bytes:this.bytes,errors:this.errors,exitCode:this.exitCode,httpStatusCode:this.httpStatusCode}}get json(){return JSON.parse(this.text)}get text(){return new TextDecoder().decode(this.bytes)}}const DEFAULT_BASE_URL="http://example.com";function toRelativeUrl(e){return e.toString().substring(e.origin.length)}function removePathPrefix(e,t){return!t||!e.startsWith(t)?e:e.substring(t.length)}function ensurePathPrefix(e,t){return!t||e.startsWith(t)?e:t+e}async function encodeAsMultipart(e){const t=`----${Math.random().toString(36).slice(2)}`,r=`multipart/form-data; boundary=${t}`,s=new TextEncoder,n=[];for(const[c,u]of Object.entries(e))n.push(`--${t}\r
36
+ `),n.push(`Content-Disposition: form-data; name="${c}"`),u instanceof File&&n.push(`; filename="${u.name}"`),n.push(`\r
37
+ `),u instanceof File&&(n.push("Content-Type: application/octet-stream"),n.push(`\r
38
38
  `)),n.push(`\r
39
- `),d instanceof File?n.push(await fileToUint8Array(d)):n.push(d),n.push(`\r
39
+ `),u instanceof File?n.push(await fileToUint8Array(u)):n.push(u),n.push(`\r
40
40
  `);n.push(`--${t}--\r
41
- `);const i=n.reduce((c,d)=>c+d.length,0),o=new Uint8Array(i);let a=0;for(const c of n)o.set(typeof c=="string"?s.encode(c):c,a),a+=c.length;return{bytes:o,contentType:r}}function fileToUint8Array(e){return new Promise(t=>{const r=new FileReader;r.onload=()=>{t(new Uint8Array(r.result))},r.readAsArrayBuffer(e)})}var m,F,N,R,x,_,C,b,I,K,O,Z,U,X;class PHPRequestHandler{constructor(t,r={}){u(this,I);u(this,O);u(this,U);u(this,m,void 0);u(this,F,void 0);u(this,N,void 0);u(this,R,void 0);u(this,x,void 0);u(this,_,void 0);u(this,C,void 0);u(this,b,void 0);h(this,b,new Semaphore({concurrency:1}));const{documentRoot:s="/www/",absoluteUrl:n=typeof location=="object"?location==null?void 0:location.href:"",rewriteRules:i=[]}=r;this.php=t,h(this,m,s);const o=new URL(n);h(this,N,o.hostname),h(this,R,o.port?Number(o.port):o.protocol==="https:"?443:80),h(this,F,(o.protocol||"").replace(":",""));const a=l(this,R)!==443&&l(this,R)!==80;h(this,x,[l(this,N),a?`:${l(this,R)}`:""].join("")),h(this,_,o.pathname.replace(/\/+$/,"")),h(this,C,[`${l(this,F)}://`,l(this,x),l(this,_)].join("")),this.rewriteRules=i}pathToInternalUrl(t){return`${this.absoluteUrl}${t}`}internalUrlToPath(t){const r=new URL(t);return r.pathname.startsWith(l(this,_))&&(r.pathname=r.pathname.slice(l(this,_).length)),toRelativeUrl(r)}get isRequestRunning(){return l(this,b).running>0}get absoluteUrl(){return l(this,C)}get documentRoot(){return l(this,m)}async request(t){const r=t.url.startsWith("http://")||t.url.startsWith("https://"),s=new URL(t.url.split("#")[0],r?void 0:DEFAULT_BASE_URL),n=applyRewriteRules(removePathPrefix(decodeURIComponent(s.pathname),l(this,_)),this.rewriteRules),i=joinPaths(l(this,m),n);return seemsLikeAPHPRequestHandlerPath(i)?await f(this,O,Z).call(this,t,s):f(this,I,K).call(this,i)}}m=new WeakMap,F=new WeakMap,N=new WeakMap,R=new WeakMap,x=new WeakMap,_=new WeakMap,C=new WeakMap,b=new WeakMap,I=new WeakSet,K=function(t){if(!this.php.fileExists(t))return new PHPResponse(404,{"x-file-type":["static"]},new TextEncoder().encode("404 File not found"));const r=this.php.readFileAsBuffer(t);return new PHPResponse(200,{"content-length":[`${r.byteLength}`],"content-type":[inferMimeType(t)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},r)},O=new WeakSet,Z=async function(t,r){var n;if(l(this,b).running>0&&((n=t.headers)==null?void 0:n["x-request-issuer"])==="php")return console.warn("Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."),new PHPResponse(502,{},new TextEncoder().encode("502 Bad Gateway"));const s=await l(this,b).acquire();try{this.php.addServerGlobalEntry("REMOTE_ADDR","127.0.0.1"),this.php.addServerGlobalEntry("DOCUMENT_ROOT",l(this,m)),this.php.addServerGlobalEntry("HTTPS",l(this,C).startsWith("https://")?"on":"");let i="GET";const o={host:l(this,x),...normalizeHeaders(t.headers||{})};let a=t.body;if(typeof a=="object"&&!(a instanceof Uint8Array)){i="POST";const{bytes:d,contentType:p}=await encodeAsMultipart(a);a=d,o["content-type"]=p}let c;try{c=f(this,U,X).call(this,decodeURIComponent(r.pathname))}catch{return new PHPResponse(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:ensurePathPrefix(toRelativeUrl(r),l(this,_)),protocol:l(this,F),method:t.method||i,body:a,scriptPath:c,headers:o})}finally{s()}},U=new WeakSet,X=function(t){let r=removePathPrefix(t,l(this,_));r=applyRewriteRules(r,this.rewriteRules),r.includes(".php")?r=r.split(".php")[0]+".php":this.php.isDir(`${l(this,m)}${r}`)?(r.endsWith("/")||(r=`${r}/`),r=`${r}index.php`):r="/index.php";const s=`${l(this,m)}${r}`;if(this.php.fileExists(s))return s;throw new Error(`File not found: ${s}`)};function inferMimeType(e){switch(e.split(".").pop()){case"css":return"text/css";case"js":return"application/javascript";case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"svg":return"image/svg+xml";case"woff":return"font/woff";case"woff2":return"font/woff2";case"ttf":return"font/ttf";case"otf":return"font/otf";case"eot":return"font/eot";case"ico":return"image/x-icon";case"html":return"text/html";case"json":return"application/json";case"xml":return"application/xml";case"txt":case"md":return"text/plain";default:return"application-octet-stream"}}function seemsLikeAPHPRequestHandlerPath(e){return seemsLikeAPHPFile(e)||seemsLikeADirectoryRoot(e)}function seemsLikeAPHPFile(e){return e.endsWith(".php")||e.includes(".php/")}function seemsLikeADirectoryRoot(e){return!e.split("/").pop().includes(".")}function applyRewriteRules(e,t){for(const r of t)if(new RegExp(r.match).test(e))return e.replace(r.match,r.replacement);return e}const FileErrorCodes={0:"No error occurred. System call completed successfully.",1:"Argument list too long.",2:"Permission denied.",3:"Address in use.",4:"Address not available.",5:"Address family not supported.",6:"Resource unavailable, or operation would block.",7:"Connection already in progress.",8:"Bad file descriptor.",9:"Bad message.",10:"Device or resource busy.",11:"Operation canceled.",12:"No child processes.",13:"Connection aborted.",14:"Connection refused.",15:"Connection reset.",16:"Resource deadlock would occur.",17:"Destination address required.",18:"Mathematics argument out of domain of function.",19:"Reserved.",20:"File exists.",21:"Bad address.",22:"File too large.",23:"Host is unreachable.",24:"Identifier removed.",25:"Illegal byte sequence.",26:"Operation in progress.",27:"Interrupted function.",28:"Invalid argument.",29:"I/O error.",30:"Socket is connected.",31:"There is a directory under that path.",32:"Too many levels of symbolic links.",33:"File descriptor value too large.",34:"Too many links.",35:"Message too large.",36:"Reserved.",37:"Filename too long.",38:"Network is down.",39:"Connection aborted by network.",40:"Network unreachable.",41:"Too many files open in system.",42:"No buffer space available.",43:"No such device.",44:"There is no such file or directory OR the parent directory does not exist.",45:"Executable file format error.",46:"No locks available.",47:"Reserved.",48:"Not enough space.",49:"No message of the desired type.",50:"Protocol not available.",51:"No space left on device.",52:"Function not supported.",53:"The socket is not connected.",54:"Not a directory or a symbolic link to a directory.",55:"Directory not empty.",56:"State not recoverable.",57:"Not a socket.",58:"Not supported, or operation not supported on socket.",59:"Inappropriate I/O control operation.",60:"No such device or address.",61:"Value too large to be stored in data type.",62:"Previous owner died.",63:"Operation not permitted.",64:"Broken pipe.",65:"Protocol error.",66:"Protocol not supported.",67:"Protocol wrong type for socket.",68:"Result too large.",69:"Read-only file system.",70:"Invalid seek.",71:"No such process.",72:"Reserved.",73:"Connection timed out.",74:"Text file busy.",75:"Cross-device link.",76:"Extension: Capabilities insufficient."};function getEmscriptenFsError(e){const t=typeof e=="object"?e==null?void 0:e.errno:null;if(t in FileErrorCodes)return FileErrorCodes[t]}function rethrowFileSystemError(e=""){return function(r,s,n){const i=n.value;n.value=function(...o){try{return i.apply(this,o)}catch(a){const c=typeof a=="object"?a==null?void 0:a.errno:null;if(c in FileErrorCodes){const d=FileErrorCodes[c],p=typeof o[0]=="string"?o[0]:null,P=p!==null?e.replaceAll("{path}",p):e;throw new Error(`${P}: ${d}`,{cause:a})}throw a}}}}const loadedRuntimes=new Map;function getLoadedRuntime(e){return loadedRuntimes.get(e)}(function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"})();var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__decorateClass=(e,t,r,s)=>{for(var n=s>1?void 0:s?__getOwnPropDesc(t,r):t,i=e.length-1,o;i>=0;i--)(o=e[i])&&(n=(s?o(t,r,n):o(n))||n);return s&&n&&__defProp(t,r,n),n};const STRING="string",NUMBER="number",__private__dont__use=Symbol("__private__dont__use");var S,k,A,y,w,g,E,H,M,ee,B,te,L,re,D,se,q,ne,$,ie,W,oe,j,ae,z,le,G,ce,J,ue,Q,de;class BasePHP{constructor(e,t){u(this,M);u(this,B);u(this,L);u(this,D);u(this,q);u(this,$);u(this,W);u(this,j);u(this,z);u(this,G);u(this,J);u(this,Q);u(this,S,void 0);u(this,k,void 0);u(this,A,void 0);u(this,y,void 0);u(this,w,void 0);u(this,g,void 0);u(this,E,void 0);u(this,H,void 0);h(this,S,[]),h(this,y,!1),h(this,w,null),h(this,g,{}),h(this,E,new Map),h(this,H,[]),this.semaphore=new Semaphore({concurrency:1}),e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new PHPBrowser(new PHPRequestHandler(this,t)))}addEventListener(e,t){l(this,E).has(e)||l(this,E).set(e,new Set),l(this,E).get(e).add(t)}removeEventListener(e,t){var r;(r=l(this,E).get(e))==null||r.delete(t)}dispatchEvent(e){const t=l(this,E).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){l(this,H).push(e)}async setSpawnHandler(handler){typeof handler=="string"&&(handler=createSpawnHandler(eval(handler))),this[__private__dont__use].spawnProcess=handler}get absoluteUrl(){return this.requestHandler.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.requestHandler.documentRoot}pathToInternalUrl(e){return this.requestHandler.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.requestHandler.internalUrlToPath(e)}initializeRuntime(e){if(this[__private__dont__use])throw new Error("PHP runtime already initialized.");const t=getLoadedRuntime(e);if(!t)throw new Error("Invalid PHP runtime id.");this[__private__dont__use]=t,t.onMessage=async r=>{for(const s of l(this,H)){const n=await s(r);if(n)return n}return""},h(this,w,improveWASMErrorReporting(t)),this.dispatchEvent({type:"runtime.initialized"})}async setSapiName(e){if(this[__private__dont__use].ccall("wasm_set_sapi_name",NUMBER,[STRING],[e])!==0)throw new Error("Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?");h(this,A,e)}setPhpIniPath(e){if(l(this,y))throw new Error("Cannot set PHP ini path after calling run().");h(this,k,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(l(this,y))throw new Error("Cannot set PHP ini entries after calling run().");l(this,S).push([e,t])}chdir(e){this[__private__dont__use].FS.chdir(e)}async request(e,t){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e,t)}async run(e){const t=await this.semaphore.acquire();let r;try{if(l(this,y)||(f(this,M,ee).call(this),h(this,y,!0)),e.scriptPath&&!this.fileExists(e.scriptPath))throw new Error(`The script path "${e.scriptPath}" does not exist.`);f(this,j,ae).call(this,e.scriptPath||""),f(this,L,re).call(this,e.relativeUri||""),f(this,q,ne).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),n=s.host||"example.com:443";f(this,D,se).call(this,n,e.protocol||"http"),f(this,$,ie).call(this,s),e.body&&(r=f(this,W,oe).call(this,e.body)),typeof e.code=="string"&&f(this,J,ue).call(this," ?>"+e.code),f(this,z,le).call(this);const i=e.env||{};for(const a in i)f(this,G,ce).call(this,a,i[a]);const o=await f(this,Q,de).call(this);if(o.exitCode!==0){console.warn("PHP.run() output was:",o.text);const a=new Error(`PHP.run() failed with exit code ${o.exitCode} and the following output: `+o.errors);throw a.response=o,a.source="request",console.error(a),a}return o}catch(s){throw this.dispatchEvent({type:"request.error",error:s,source:s.source??"php-wasm"}),s}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){l(this,g)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/internal/consts.json")&&this.readFileAsText("/internal/consts.json")||"{}")}catch{}this.writeFile("/internal/consts.json",JSON.stringify({...r,[e]:t}))}mkdir(e){this[__private__dont__use].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[__private__dont__use].FS.readFile(e)}writeFile(e,t){this[__private__dont__use].FS.writeFile(e,t)}unlink(e){this[__private__dont__use].FS.unlink(e)}mv(e,t){try{this[__private__dont__use].FS.rename(e,t)}catch(r){const s=getEmscriptenFsError(r);throw s?new Error(`Could not move ${e} to ${t}: ${s}`,{cause:r}):r}}rmdir(e,t={recursive:!0}){t!=null&&t.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[__private__dont__use].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[__private__dont__use].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(n=>`${s}/${n}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[__private__dont__use].FS.isDir(this[__private__dont__use].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[__private__dont__use].FS.lookupPath(e),!0}catch{return!1}}hotSwapPHPRuntime(e){const t=this[__private__dont__use].FS;try{this.exit()}catch{}if(this.initializeRuntime(e),l(this,k)&&this.setPhpIniPath(l(this,k)),l(this,A)&&this.setSapiName(l(this,A)),this.requestHandler){const r=this.documentRoot;copyFS(t,this[__private__dont__use].FS,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}h(this,y,!1),h(this,w,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}S=new WeakMap,k=new WeakMap,A=new WeakMap,y=new WeakMap,w=new WeakMap,g=new WeakMap,E=new WeakMap,H=new WeakMap,M=new WeakSet,ee=function(){if(this.setPhpIniEntry("auto_prepend_file","/internal/consts.php"),this.fileExists("/internal/consts.php")||this.writeFile("/internal/consts.php",`<?php
41
+ `);const i=n.reduce((c,u)=>c+u.length,0),o=new Uint8Array(i);let a=0;for(const c of n)o.set(typeof c=="string"?s.encode(c):c,a),a+=c.length;return{bytes:o,contentType:r}}function fileToUint8Array(e){return new Promise(t=>{const r=new FileReader;r.onload=()=>{t(new Uint8Array(r.result))},r.readAsArrayBuffer(e)})}class HttpCookieStore{constructor(){this.cookies={}}rememberCookiesFromResponseHeaders(t){if(t!=null&&t["set-cookie"])for(const r of t["set-cookie"])try{if(!r.includes("="))continue;const s=r.indexOf("="),n=r.substring(0,s),i=r.substring(s+1).split(";")[0];this.cookies[n]=i}catch(s){console.error(s)}}getCookieRequestHeader(){const t=[];for(const r in this.cookies)t.push(`${r}=${this.cookies[r]}`);return t.join("; ")}}var m,b,A,P,S,_,T,v,F,H,Z,N,X,O,ee;class PHPRequestHandler{constructor(t,r={}){d(this,H);d(this,N);d(this,O);d(this,m,void 0);d(this,b,void 0);d(this,A,void 0);d(this,P,void 0);d(this,S,void 0);d(this,_,void 0);d(this,T,void 0);d(this,v,void 0);d(this,F,void 0);p(this,v,new Semaphore({concurrency:1}));const{documentRoot:s="/www/",absoluteUrl:n=typeof location=="object"?location==null?void 0:location.href:"",rewriteRules:i=[]}=r;this.php=t,p(this,F,new HttpCookieStore),p(this,m,s);const o=new URL(n);p(this,A,o.hostname),p(this,P,o.port?Number(o.port):o.protocol==="https:"?443:80),p(this,b,(o.protocol||"").replace(":",""));const a=l(this,P)!==443&&l(this,P)!==80;p(this,S,[l(this,A),a?`:${l(this,P)}`:""].join("")),p(this,_,o.pathname.replace(/\/+$/,"")),p(this,T,[`${l(this,b)}://`,l(this,S),l(this,_)].join("")),this.rewriteRules=i}pathToInternalUrl(t){return`${this.absoluteUrl}${t}`}internalUrlToPath(t){const r=new URL(t);return r.pathname.startsWith(l(this,_))&&(r.pathname=r.pathname.slice(l(this,_).length)),toRelativeUrl(r)}get isRequestRunning(){return l(this,v).running>0}get absoluteUrl(){return l(this,T)}get documentRoot(){return l(this,m)}async request(t){const r=t.url.startsWith("http://")||t.url.startsWith("https://"),s=new URL(t.url.split("#")[0],r?void 0:DEFAULT_BASE_URL),n=applyRewriteRules(removePathPrefix(decodeURIComponent(s.pathname),l(this,_)),this.rewriteRules),i=joinPaths(l(this,m),n);return seemsLikeAPHPRequestHandlerPath(i)?await f(this,N,X).call(this,t,s):f(this,H,Z).call(this,i)}}m=new WeakMap,b=new WeakMap,A=new WeakMap,P=new WeakMap,S=new WeakMap,_=new WeakMap,T=new WeakMap,v=new WeakMap,F=new WeakMap,H=new WeakSet,Z=function(t){if(!this.php.fileExists(t))return new PHPResponse(404,{"x-file-type":["static"]},new TextEncoder().encode("404 File not found"));const r=this.php.readFileAsBuffer(t);return new PHPResponse(200,{"content-length":[`${r.byteLength}`],"content-type":[inferMimeType(t)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},r)},N=new WeakSet,X=async function(t,r){var n;if(l(this,v).running>0&&((n=t.headers)==null?void 0:n["x-request-issuer"])==="php")return console.warn("Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."),new PHPResponse(502,{},new TextEncoder().encode("502 Bad Gateway"));const s=await l(this,v).acquire();try{let i="GET";const o={host:l(this,S),...normalizeHeaders(t.headers||{}),cookie:l(this,F).getCookieRequestHeader()};let a=t.body;if(typeof a=="object"&&!(a instanceof Uint8Array)){i="POST";const{bytes:u,contentType:h}=await encodeAsMultipart(a);a=u,o["content-type"]=h}let c;try{c=f(this,O,ee).call(this,decodeURIComponent(r.pathname))}catch{return new PHPResponse(404,{},new TextEncoder().encode("404 File not found"))}try{const u=await this.php.run({relativeUri:ensurePathPrefix(toRelativeUrl(r),l(this,_)),protocol:l(this,b),method:t.method||i,$_SERVER:{REMOTE_ADDR:"127.0.0.1",DOCUMENT_ROOT:l(this,m),HTTPS:l(this,T).startsWith("https://")?"on":""},body:a,scriptPath:c,headers:o});return l(this,F).rememberCookiesFromResponseHeaders(u.headers),u}catch(u){const h=u;if(h!=null&&h.response)return h.response;throw u}}finally{s()}},O=new WeakSet,ee=function(t){let r=removePathPrefix(t,l(this,_));r=applyRewriteRules(r,this.rewriteRules),r.includes(".php")?r=r.split(".php")[0]+".php":this.php.isDir(`${l(this,m)}${r}`)?(r.endsWith("/")||(r=`${r}/`),r=`${r}index.php`):r="/index.php";const s=`${l(this,m)}${r}`;if(this.php.fileExists(s))return s;throw new Error(`File not found: ${s}`)};function inferMimeType(e){switch(e.split(".").pop()){case"css":return"text/css";case"js":return"application/javascript";case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"svg":return"image/svg+xml";case"woff":return"font/woff";case"woff2":return"font/woff2";case"ttf":return"font/ttf";case"otf":return"font/otf";case"eot":return"font/eot";case"ico":return"image/x-icon";case"html":return"text/html";case"json":return"application/json";case"xml":return"application/xml";case"txt":case"md":return"text/plain";case"pdf":return"application/pdf";case"webp":return"image/webp";case"mp3":return"audio/mpeg";case"mp4":return"video/mp4";case"csv":return"text/csv";case"xls":return"application/vnd.ms-excel";case"xlsx":return"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";case"doc":return"application/msword";case"docx":return"application/vnd.openxmlformats-officedocument.wordprocessingml.document";case"ppt":return"application/vnd.ms-powerpoint";case"pptx":return"application/vnd.openxmlformats-officedocument.presentationml.presentation";case"zip":return"application/zip";case"rar":return"application/x-rar-compressed";case"tar":return"application/x-tar";case"gz":return"application/gzip";case"7z":return"application/x-7z-compressed";default:return"application-octet-stream"}}function seemsLikeAPHPRequestHandlerPath(e){return seemsLikeAPHPFile(e)||seemsLikeADirectoryRoot(e)}function seemsLikeAPHPFile(e){return e.endsWith(".php")||e.includes(".php/")}function seemsLikeADirectoryRoot(e){return!e.split("/").pop().includes(".")}function applyRewriteRules(e,t){for(const r of t)if(new RegExp(r.match).test(e))return e.replace(r.match,r.replacement);return e}const FileErrorCodes={0:"No error occurred. System call completed successfully.",1:"Argument list too long.",2:"Permission denied.",3:"Address in use.",4:"Address not available.",5:"Address family not supported.",6:"Resource unavailable, or operation would block.",7:"Connection already in progress.",8:"Bad file descriptor.",9:"Bad message.",10:"Device or resource busy.",11:"Operation canceled.",12:"No child processes.",13:"Connection aborted.",14:"Connection refused.",15:"Connection reset.",16:"Resource deadlock would occur.",17:"Destination address required.",18:"Mathematics argument out of domain of function.",19:"Reserved.",20:"File exists.",21:"Bad address.",22:"File too large.",23:"Host is unreachable.",24:"Identifier removed.",25:"Illegal byte sequence.",26:"Operation in progress.",27:"Interrupted function.",28:"Invalid argument.",29:"I/O error.",30:"Socket is connected.",31:"There is a directory under that path.",32:"Too many levels of symbolic links.",33:"File descriptor value too large.",34:"Too many links.",35:"Message too large.",36:"Reserved.",37:"Filename too long.",38:"Network is down.",39:"Connection aborted by network.",40:"Network unreachable.",41:"Too many files open in system.",42:"No buffer space available.",43:"No such device.",44:"There is no such file or directory OR the parent directory does not exist.",45:"Executable file format error.",46:"No locks available.",47:"Reserved.",48:"Not enough space.",49:"No message of the desired type.",50:"Protocol not available.",51:"No space left on device.",52:"Function not supported.",53:"The socket is not connected.",54:"Not a directory or a symbolic link to a directory.",55:"Directory not empty.",56:"State not recoverable.",57:"Not a socket.",58:"Not supported, or operation not supported on socket.",59:"Inappropriate I/O control operation.",60:"No such device or address.",61:"Value too large to be stored in data type.",62:"Previous owner died.",63:"Operation not permitted.",64:"Broken pipe.",65:"Protocol error.",66:"Protocol not supported.",67:"Protocol wrong type for socket.",68:"Result too large.",69:"Read-only file system.",70:"Invalid seek.",71:"No such process.",72:"Reserved.",73:"Connection timed out.",74:"Text file busy.",75:"Cross-device link.",76:"Extension: Capabilities insufficient."};function getEmscriptenFsError(e){const t=typeof e=="object"?e==null?void 0:e.errno:null;if(t in FileErrorCodes)return FileErrorCodes[t]}function rethrowFileSystemError(e=""){return function(r,s,n){const i=n.value;n.value=function(...o){try{return i.apply(this,o)}catch(a){const c=typeof a=="object"?a==null?void 0:a.errno:null;if(c in FileErrorCodes){const u=FileErrorCodes[c],h=typeof o[0]=="string"?o[0]:null,g=h!==null?e.replaceAll("{path}",h):e;throw new Error(`${g}: ${u}`,{cause:a})}throw a}}}}const loadedRuntimes=new Map;function getLoadedRuntime(e){return loadedRuntimes.get(e)}(function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"})();var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__decorateClass=(e,t,r,s)=>{for(var n=s>1?void 0:s?__getOwnPropDesc(t,r):t,i=e.length-1,o;i>=0;i--)(o=e[i])&&(n=(s?o(t,r,n):o(n))||n);return s&&n&&__defProp(t,r,n),n};const STRING="string",NUMBER="number",__private__dont__use=Symbol("__private__dont__use");class PHPExecutionFailureError extends Error{constructor(t,r,s){super(t),this.response=r,this.source=s}}var R,x,k,y,w,E,C,I,te,M,re,U,se,B,ne,L,ie,D,oe,$,ae,q,le,j,ce,W,ue,z,de,G,he,J,pe,V,fe,Q,_e;class BasePHP{constructor(e,t){d(this,I);d(this,M);d(this,U);d(this,B);d(this,L);d(this,D);d(this,$);d(this,q);d(this,j);d(this,W);d(this,z);d(this,G);d(this,J);d(this,V);d(this,Q);d(this,R,void 0);d(this,x,void 0);d(this,k,void 0);d(this,y,void 0);d(this,w,void 0);d(this,E,void 0);d(this,C,void 0);p(this,R,[]),p(this,y,!1),p(this,w,null),p(this,E,new Map),p(this,C,[]),this.semaphore=new Semaphore({concurrency:1}),e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new PHPRequestHandler(this,t))}addEventListener(e,t){l(this,E).has(e)||l(this,E).set(e,new Set),l(this,E).get(e).add(t)}removeEventListener(e,t){var r;(r=l(this,E).get(e))==null||r.delete(t)}dispatchEvent(e){const t=l(this,E).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){l(this,C).push(e)}async setSpawnHandler(handler){typeof handler=="string"&&(handler=createSpawnHandler(eval(handler))),this[__private__dont__use].spawnProcess=handler}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}pathToInternalUrl(e){return this.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.internalUrlToPath(e)}initializeRuntime(e){if(this[__private__dont__use])throw new Error("PHP runtime already initialized.");const t=getLoadedRuntime(e);if(!t)throw new Error("Invalid PHP runtime id.");this[__private__dont__use]=t,t.onMessage=async r=>{for(const s of l(this,C)){const n=await s(r);if(n)return n}return""},p(this,w,improveWASMErrorReporting(t)),this.dispatchEvent({type:"runtime.initialized"})}async setSapiName(e){if(this[__private__dont__use].ccall("wasm_set_sapi_name",NUMBER,[STRING],[e])!==0)throw new Error("Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?");p(this,k,e)}setPhpIniPath(e){if(l(this,y))throw new Error("Cannot set PHP ini path after calling run().");p(this,x,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(l(this,y))throw new Error("Cannot set PHP ini entries after calling run().");l(this,R).push([e,t])}chdir(e){this[__private__dont__use].FS.chdir(e)}async request(e){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e)}async run(e){const t=await this.semaphore.acquire();let r;try{if(l(this,y)||(f(this,M,re).call(this),p(this,y,!0)),e.scriptPath&&!this.fileExists(e.scriptPath))throw new Error(`The script path "${e.scriptPath}" does not exist.`);f(this,z,de).call(this,e.scriptPath||""),f(this,B,ne).call(this,e.relativeUri||""),f(this,q,le).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),n=s.host||"example.com:443",i=f(this,$,ae).call(this,n,e.protocol||"http");f(this,L,ie).call(this,n),f(this,D,oe).call(this,i),f(this,j,ce).call(this,s),e.body&&(r=f(this,W,ue).call(this,e.body)),typeof e.code=="string"&&f(this,V,fe).call(this," ?>"+e.code);const o=f(this,I,te).call(this,e.$_SERVER,s,i);for(const u in o)f(this,G,he).call(this,u,o[u]);const a=e.env||{};for(const u in a)f(this,J,pe).call(this,u,a[u]);const c=await f(this,Q,_e).call(this);if(c.exitCode!==0){console.warn("PHP.run() output was:",c.text);const u=new PHPExecutionFailureError(`PHP.run() failed with exit code ${c.exitCode} and the following output: `+c.errors,c,"request");throw console.error(u),u}return c}catch(s){throw this.dispatchEvent({type:"request.error",error:s,source:s.source??"php-wasm"}),s}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/internal/consts.json")&&this.readFileAsText("/internal/consts.json")||"{}")}catch{}this.writeFile("/internal/consts.json",JSON.stringify({...r,[e]:t}))}mkdir(e){this[__private__dont__use].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[__private__dont__use].FS.readFile(e)}writeFile(e,t){this[__private__dont__use].FS.writeFile(e,t)}unlink(e){this[__private__dont__use].FS.unlink(e)}mv(e,t){try{this[__private__dont__use].FS.rename(e,t)}catch(r){const s=getEmscriptenFsError(r);throw s?new Error(`Could not move ${e} to ${t}: ${s}`,{cause:r}):r}}rmdir(e,t={recursive:!0}){t!=null&&t.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[__private__dont__use].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[__private__dont__use].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(n=>`${s}/${n}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[__private__dont__use].FS.isDir(this[__private__dont__use].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[__private__dont__use].FS.lookupPath(e),!0}catch{return!1}}hotSwapPHPRuntime(e,t){const r=this[__private__dont__use].FS;try{this.exit()}catch{}this.initializeRuntime(e),l(this,x)&&this.setPhpIniPath(l(this,x)),l(this,k)&&this.setSapiName(l(this,k)),t&&copyFS(r,this[__private__dont__use].FS,t)}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}p(this,y,!1),p(this,w,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}R=new WeakMap,x=new WeakMap,k=new WeakMap,y=new WeakMap,w=new WeakMap,E=new WeakMap,C=new WeakMap,I=new WeakSet,te=function(e,t,r){const s={...e||{}};s.HTTPS=s.HTTPS||r===443?"on":"off";for(const n in t){let i="HTTP_";["content-type","content-length"].includes(n.toLowerCase())&&(i=""),s[`${i}${n.toUpperCase().replace(/-/g,"_")}`]=t[n]}return s},M=new WeakSet,re=function(){if(this.setPhpIniEntry("auto_prepend_file","/internal/consts.php"),this.fileExists("/internal/consts.php")||this.writeFile("/internal/consts.php",`<?php
42
42
  if(file_exists('/internal/consts.json')) {
43
43
  $consts = json_decode(file_get_contents('/internal/consts.json'), true);
44
44
  foreach ($consts as $const => $value) {
@@ -46,7 +46,7 @@ ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
46
46
  define($const, $value);
47
47
  }
48
48
  }
49
- }`),l(this,S).length>0){const e=l(this,S).map(([t,r])=>`${t}=${r}`).join(`
49
+ }`),l(this,R).length>0){const e=l(this,R).map(([t,r])=>`${t}=${r}`).join(`
50
50
  `)+`
51
51
 
52
- `;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},B=new WeakSet,te=function(){const e="/internal/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const t=JSON.parse(this.readFileAsText(e)),r={};for(const s of t.headers){if(!s.includes(": "))continue;const n=s.indexOf(": "),i=s.substring(0,n).toLowerCase(),o=s.substring(n+2);i in r||(r[i]=[]),r[i].push(o)}return{headers:r,httpStatusCode:t.status}},L=new WeakSet,re=function(e){if(this[__private__dont__use].ccall("wasm_set_request_uri",null,[STRING],[e]),e.includes("?")){const t=e.substring(e.indexOf("?")+1);this[__private__dont__use].ccall("wasm_set_query_string",null,[STRING],[t])}},D=new WeakSet,se=function(e,t){this[__private__dont__use].ccall("wasm_set_request_host",null,[STRING],[e]);let r;try{r=parseInt(new URL(e).port,10)}catch{}(!r||isNaN(r)||r===80)&&(r=t==="https"?443:80),this[__private__dont__use].ccall("wasm_set_request_port",null,[NUMBER],[r]),(t==="https"||!t&&r===443)&&this.addServerGlobalEntry("HTTPS","on")},q=new WeakSet,ne=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},$=new WeakSet,ie=function(e){e.cookie&&this[__private__dont__use].ccall("wasm_set_cookies",null,[STRING],[e.cookie]),e["content-type"]&&this[__private__dont__use].ccall("wasm_set_content_type",null,[STRING],[e["content-type"]]),e["content-length"]&&this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[parseInt(e["content-length"],10)]);for(const t in e){let r="HTTP_";["content-type","content-length"].includes(t.toLowerCase())&&(r=""),this.addServerGlobalEntry(`${r}${t.toUpperCase().replace(/-/g,"_")}`,e[t])}},W=new WeakSet,oe=function(e){let t,r;typeof e=="string"?(console.warn("Passing a string as the request body is deprecated. Please use a Uint8Array instead. See https://github.com/WordPress/wordpress-playground/issues/997 for more details"),r=this[__private__dont__use].lengthBytesUTF8(e),t=r+1):(r=e.byteLength,t=e.byteLength);const s=this[__private__dont__use].malloc(t);if(!s)throw new Error("Could not allocate memory for the request body.");return typeof e=="string"?this[__private__dont__use].stringToUTF8(e,s,t+1):this[__private__dont__use].HEAPU8.set(e,s),this[__private__dont__use].ccall("wasm_set_request_body",null,[NUMBER],[s]),this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[r]),s},j=new WeakSet,ae=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},z=new WeakSet,le=function(){for(const e in l(this,g))this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,l(this,g)[e]])},G=new WeakSet,ce=function(e,t){this[__private__dont__use].ccall("wasm_add_ENV_entry",null,[STRING,STRING],[e,t])},J=new WeakSet,ue=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},Q=new WeakSet,de=async function(){var n;let e,t;try{e=await new Promise((i,o)=>{var c;t=d=>{console.error(d),console.error(d.error);const p=new Error("Rethrown");p.cause=d.error,p.betterMessage=d.message,o(p)},(c=l(this,w))==null||c.addEventListener("error",t);const a=this[__private__dont__use].ccall("wasm_sapi_handle_request",NUMBER,[],[],{async:!0});return a instanceof Promise?a.then(i,o):i(a)})}catch(i){for(const d in this)typeof this[d]=="function"&&(this[d]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=getFunctionsMaybeMissingFromAsyncify();const o=i,a="betterMessage"in o?o.betterMessage:o.message,c=new Error(a);throw c.cause=o,console.error(c),c}finally{(n=l(this,w))==null||n.removeEventListener("error",t),h(this,g,{})}const{headers:r,httpStatusCode:s}=f(this,B,te).call(this);return new PHPResponse(s,r,this.readFileAsBuffer("/internal/stdout"),this.readFileAsText("/internal/stderr"),e)};__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdir",1);__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdirTree",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsText",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsBuffer",1);__decorateClass([rethrowFileSystemError('Could not write to "{path}"')],BasePHP.prototype,"writeFile",1);__decorateClass([rethrowFileSystemError('Could not unlink "{path}"')],BasePHP.prototype,"unlink",1);__decorateClass([rethrowFileSystemError('Could not remove directory "{path}"')],BasePHP.prototype,"rmdir",1);__decorateClass([rethrowFileSystemError('Could not list files in "{path}"')],BasePHP.prototype,"listFiles",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"isDir",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"fileExists",1);function normalizeHeaders(e){const t={};for(const r in e)t[r.toLowerCase()]=e[r];return t}function copyFS(e,t,r){let s;try{s=e.lookupPath(r)}catch{return}if(!("contents"in s.node))return;if(!e.isDir(s.node.mode)){t.writeFile(r,e.readFile(r));return}t.mkdirTree(r);const n=e.readdir(r).filter(i=>i!=="."&&i!=="..");for(const i of n)copyFS(e,t,joinPaths(r,i))}function journalFSEvents(e,t,r=()=>{}){function s(){t=normalizePath(t);const i=e[__private__dont__use].FS,o=createFSHooks(i,p=>{if(p.path.startsWith(t))r(p);else if(p.operation==="RENAME"&&p.toPath.startsWith(t))for(const P of recordExistingPath(e,p.path,p.toPath))r(P)}),a={};for(const[p]of Object.entries(o))a[p]=i[p];function c(){for(const[p,P]of Object.entries(o))i[p]=function(...V){return P(...V),a[p].apply(this,V)}}function d(){for(const[p,P]of Object.entries(a))e[__private__dont__use].FS[p]=P}e[__private__dont__use].journal={bind:c,unbind:d},c()}e.addEventListener("runtime.initialized",s),e[__private__dont__use]&&s();function n(){e[__private__dont__use].journal.unbind(),delete e[__private__dont__use].journal}return e.addEventListener("runtime.beforedestroy",n),function(){return e.removeEventListener("runtime.initialized",s),e.removeEventListener("runtime.beforedestroy",n),e[__private__dont__use].journal.unbind()}}const createFSHooks=(e,t=()=>{})=>({write(r){t({operation:"WRITE",path:r.path,nodeType:"file"})},truncate(r){let s;typeof r=="string"?s=e.lookupPath(r,{follow:!0}).node:s=r,t({operation:"WRITE",path:e.getPath(s),nodeType:"file"})},unlink(r){t({operation:"DELETE",path:r,nodeType:"file"})},mknod(r,s){e.isFile(s)&&t({operation:"CREATE",path:r,nodeType:"file"})},mkdir(r){t({operation:"CREATE",path:r,nodeType:"directory"})},rmdir(r){t({operation:"DELETE",path:r,nodeType:"directory"})},rename(r,s){try{const n=e.lookupPath(r,{follow:!0}),i=e.lookupPath(s,{parent:!0}).path;t({operation:"RENAME",nodeType:e.isDir(n.node.mode)?"directory":"file",path:n.path,toPath:joinPaths(i,basename(s))})}catch{}}});function replayFSJournal(e,t){e[__private__dont__use].journal.unbind();try{for(const r of t)r.operation==="CREATE"?r.nodeType==="file"?e.writeFile(r.path," "):e.mkdir(r.path):r.operation==="DELETE"?r.nodeType==="file"?e.unlink(r.path):e.rmdir(r.path):r.operation==="WRITE"?e.writeFile(r.path,r.data):r.operation==="RENAME"&&e.mv(r.path,r.toPath)}finally{e[__private__dont__use].journal.bind()}}function*recordExistingPath(e,t,r){if(e.isDir(t)){yield{operation:"CREATE",path:r,nodeType:"directory"};for(const s of e.listFiles(t))yield*recordExistingPath(e,joinPaths(t,s),joinPaths(r,s))}else yield{operation:"CREATE",path:r,nodeType:"file"},yield{operation:"WRITE",nodeType:"file",path:r}}function normalizePath(e){return e.replace(/\/$/,"").replace(/\/\/+/g,"/")}function normalizeFilesystemOperations(e){const t={};for(let r=e.length-1;r>=0;r--){for(let s=r-1;s>=0;s--){const n=checkRelationship(e[r],e[s]);if(n==="none")continue;const i=e[r],o=e[s];if(i.operation==="RENAME"&&o.operation==="RENAME"){console.warn("[FS Journal] Normalizing a double rename is not yet supported:",{current:i,last:o});continue}(o.operation==="CREATE"||o.operation==="WRITE")&&(i.operation==="RENAME"?n==="same_node"?(t[s]=[],t[r]=[{...o,path:i.toPath},...t[r]||[]]):n==="descendant"&&(t[s]=[],t[r]=[{...o,path:joinPaths(i.toPath,o.path.substring(i.path.length))},...t[r]||[]]):i.operation==="WRITE"&&n==="same_node"?t[s]=[]:i.operation==="DELETE"&&n==="same_node"&&(t[s]=[],t[r]=[]))}if(Object.entries(t).length>0){const s=e.flatMap((n,i)=>i in t?t[i]:[n]);return normalizeFilesystemOperations(s)}}return e}function checkRelationship(e,t){const r=e.path,s=e.operation!=="WRITE"&&e.nodeType==="directory",n=t.operation!=="WRITE"&&t.nodeType==="directory",i=t.operation==="RENAME"?t.toPath:t.path;return i===r?"same_node":n&&r.startsWith(i+"/")?"ancestor":s&&i.startsWith(r+"/")?"descendant":"none"}async function hydrateUpdateFileOps(e,t){const s=t.filter(n=>n.operation==="WRITE").map(n=>hydrateOp(e,n));return await Promise.all(s),t}const hydrateLock=new Semaphore({concurrency:15});async function hydrateOp(e,t){const r=await hydrateLock.acquire();try{t.data=await e.readFileAsBuffer(t.path)}catch(s){console.warn(`Journal failed to hydrate a file on flush: the path ${t.path} no longer exists`),console.error(s)}r()}exports.hydrateUpdateFileOps=hydrateUpdateFileOps;exports.journalFSEvents=journalFSEvents;exports.normalizeFilesystemOperations=normalizeFilesystemOperations;exports.replayFSJournal=replayFSJournal;
52
+ `;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},U=new WeakSet,se=function(){const e="/internal/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const t=JSON.parse(this.readFileAsText(e)),r={};for(const s of t.headers){if(!s.includes(": "))continue;const n=s.indexOf(": "),i=s.substring(0,n).toLowerCase(),o=s.substring(n+2);i in r||(r[i]=[]),r[i].push(o)}return{headers:r,httpStatusCode:t.status}},B=new WeakSet,ne=function(e){if(this[__private__dont__use].ccall("wasm_set_request_uri",null,[STRING],[e]),e.includes("?")){const t=e.substring(e.indexOf("?")+1);this[__private__dont__use].ccall("wasm_set_query_string",null,[STRING],[t])}},L=new WeakSet,ie=function(e){this[__private__dont__use].ccall("wasm_set_request_host",null,[STRING],[e])},D=new WeakSet,oe=function(e){this[__private__dont__use].ccall("wasm_set_request_port",null,[NUMBER],[e])},$=new WeakSet,ae=function(e,t){let r;try{r=parseInt(new URL(e).port,10)}catch{}return(!r||isNaN(r)||r===80)&&(r=t==="https"?443:80),r},q=new WeakSet,le=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},j=new WeakSet,ce=function(e){e.cookie&&this[__private__dont__use].ccall("wasm_set_cookies",null,[STRING],[e.cookie]),e["content-type"]&&this[__private__dont__use].ccall("wasm_set_content_type",null,[STRING],[e["content-type"]]),e["content-length"]&&this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[parseInt(e["content-length"],10)])},W=new WeakSet,ue=function(e){let t,r;typeof e=="string"?(console.warn("Passing a string as the request body is deprecated. Please use a Uint8Array instead. See https://github.com/WordPress/wordpress-playground/issues/997 for more details"),r=this[__private__dont__use].lengthBytesUTF8(e),t=r+1):(r=e.byteLength,t=e.byteLength);const s=this[__private__dont__use].malloc(t);if(!s)throw new Error("Could not allocate memory for the request body.");return typeof e=="string"?this[__private__dont__use].stringToUTF8(e,s,t+1):this[__private__dont__use].HEAPU8.set(e,s),this[__private__dont__use].ccall("wasm_set_request_body",null,[NUMBER],[s]),this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[r]),s},z=new WeakSet,de=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},G=new WeakSet,he=function(e,t){this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,t])},J=new WeakSet,pe=function(e,t){this[__private__dont__use].ccall("wasm_add_ENV_entry",null,[STRING,STRING],[e,t])},V=new WeakSet,fe=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},Q=new WeakSet,_e=async function(){var n;let e,t;try{e=await new Promise((i,o)=>{var c;t=u=>{console.error(u),console.error(u.error);const h=new Error("Rethrown");h.cause=u.error,h.betterMessage=u.message,o(h)},(c=l(this,w))==null||c.addEventListener("error",t);const a=this[__private__dont__use].ccall("wasm_sapi_handle_request",NUMBER,[],[],{async:!0});return a instanceof Promise?a.then(i,o):i(a)})}catch(i){for(const u in this)typeof this[u]=="function"&&(this[u]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=getFunctionsMaybeMissingFromAsyncify();const o=i,a="betterMessage"in o?o.betterMessage:o.message,c=new Error(a);throw c.cause=o,console.error(c),c}finally{(n=l(this,w))==null||n.removeEventListener("error",t)}const{headers:r,httpStatusCode:s}=f(this,U,se).call(this);return new PHPResponse(e===0?s:500,r,this.readFileAsBuffer("/internal/stdout"),this.readFileAsText("/internal/stderr"),e)};__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdir",1);__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdirTree",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsText",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsBuffer",1);__decorateClass([rethrowFileSystemError('Could not write to "{path}"')],BasePHP.prototype,"writeFile",1);__decorateClass([rethrowFileSystemError('Could not unlink "{path}"')],BasePHP.prototype,"unlink",1);__decorateClass([rethrowFileSystemError('Could not remove directory "{path}"')],BasePHP.prototype,"rmdir",1);__decorateClass([rethrowFileSystemError('Could not list files in "{path}"')],BasePHP.prototype,"listFiles",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"isDir",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"fileExists",1);function normalizeHeaders(e){const t={};for(const r in e)t[r.toLowerCase()]=e[r];return t}function copyFS(e,t,r){let s;try{s=e.lookupPath(r)}catch{return}if(!("contents"in s.node))return;if(!e.isDir(s.node.mode)){t.writeFile(r,e.readFile(r));return}t.mkdirTree(r);const n=e.readdir(r).filter(i=>i!=="."&&i!=="..");for(const i of n)copyFS(e,t,joinPaths(r,i))}function journalFSEvents(e,t,r=()=>{}){function s(){t=normalizePath(t);const i=e[__private__dont__use].FS,o=createFSHooks(i,h=>{if(h.path.startsWith(t))r(h);else if(h.operation==="RENAME"&&h.toPath.startsWith(t))for(const g of recordExistingPath(e,h.path,h.toPath))r(g)}),a={};for(const[h]of Object.entries(o))a[h]=i[h];function c(){for(const[h,g]of Object.entries(o))i[h]=function(...K){return g(...K),a[h].apply(this,K)}}function u(){for(const[h,g]of Object.entries(a))e[__private__dont__use].FS[h]=g}e[__private__dont__use].journal={bind:c,unbind:u},c()}e.addEventListener("runtime.initialized",s),e[__private__dont__use]&&s();function n(){e[__private__dont__use].journal.unbind(),delete e[__private__dont__use].journal}return e.addEventListener("runtime.beforedestroy",n),function(){return e.removeEventListener("runtime.initialized",s),e.removeEventListener("runtime.beforedestroy",n),e[__private__dont__use].journal.unbind()}}const createFSHooks=(e,t=()=>{})=>({write(r){t({operation:"WRITE",path:r.path,nodeType:"file"})},truncate(r){let s;typeof r=="string"?s=e.lookupPath(r,{follow:!0}).node:s=r,t({operation:"WRITE",path:e.getPath(s),nodeType:"file"})},unlink(r){t({operation:"DELETE",path:r,nodeType:"file"})},mknod(r,s){e.isFile(s)&&t({operation:"CREATE",path:r,nodeType:"file"})},mkdir(r){t({operation:"CREATE",path:r,nodeType:"directory"})},rmdir(r){t({operation:"DELETE",path:r,nodeType:"directory"})},rename(r,s){try{const n=e.lookupPath(r,{follow:!0}),i=e.lookupPath(s,{parent:!0}).path;t({operation:"RENAME",nodeType:e.isDir(n.node.mode)?"directory":"file",path:n.path,toPath:joinPaths(i,basename(s))})}catch{}}});function replayFSJournal(e,t){e[__private__dont__use].journal.unbind();try{for(const r of t)r.operation==="CREATE"?r.nodeType==="file"?e.writeFile(r.path," "):e.mkdir(r.path):r.operation==="DELETE"?r.nodeType==="file"?e.unlink(r.path):e.rmdir(r.path):r.operation==="WRITE"?e.writeFile(r.path,r.data):r.operation==="RENAME"&&e.mv(r.path,r.toPath)}finally{e[__private__dont__use].journal.bind()}}function*recordExistingPath(e,t,r){if(e.isDir(t)){yield{operation:"CREATE",path:r,nodeType:"directory"};for(const s of e.listFiles(t))yield*recordExistingPath(e,joinPaths(t,s),joinPaths(r,s))}else yield{operation:"CREATE",path:r,nodeType:"file"},yield{operation:"WRITE",nodeType:"file",path:r}}function normalizePath(e){return e.replace(/\/$/,"").replace(/\/\/+/g,"/")}function normalizeFilesystemOperations(e){const t={};for(let r=e.length-1;r>=0;r--){for(let s=r-1;s>=0;s--){const n=checkRelationship(e[r],e[s]);if(n==="none")continue;const i=e[r],o=e[s];if(i.operation==="RENAME"&&o.operation==="RENAME"){console.warn("[FS Journal] Normalizing a double rename is not yet supported:",{current:i,last:o});continue}(o.operation==="CREATE"||o.operation==="WRITE")&&(i.operation==="RENAME"?n==="same_node"?(t[s]=[],t[r]=[{...o,path:i.toPath},...t[r]||[]]):n==="descendant"&&(t[s]=[],t[r]=[{...o,path:joinPaths(i.toPath,o.path.substring(i.path.length))},...t[r]||[]]):i.operation==="WRITE"&&n==="same_node"?t[s]=[]:i.operation==="DELETE"&&n==="same_node"&&(t[s]=[],t[r]=[]))}if(Object.entries(t).length>0){const s=e.flatMap((n,i)=>i in t?t[i]:[n]);return normalizeFilesystemOperations(s)}}return e}function checkRelationship(e,t){const r=e.path,s=e.operation!=="WRITE"&&e.nodeType==="directory",n=t.operation!=="WRITE"&&t.nodeType==="directory",i=t.operation==="RENAME"?t.toPath:t.path;return i===r?"same_node":n&&r.startsWith(i+"/")?"ancestor":s&&i.startsWith(r+"/")?"descendant":"none"}async function hydrateUpdateFileOps(e,t){const s=t.filter(n=>n.operation==="WRITE").map(n=>hydrateOp(e,n));return await Promise.all(s),t}const hydrateLock=new Semaphore({concurrency:15});async function hydrateOp(e,t){const r=await hydrateLock.acquire();try{t.data=await e.readFileAsBuffer(t.path)}catch(s){console.warn(`Journal failed to hydrate a file on flush: the path ${t.path} no longer exists`),console.error(s)}r()}exports.hydrateUpdateFileOps=hydrateUpdateFileOps;exports.journalFSEvents=journalFSEvents;exports.normalizeFilesystemOperations=normalizeFilesystemOperations;exports.replayFSJournal=replayFSJournal;
package/index.js CHANGED
@@ -2,11 +2,11 @@ var Y = (e, t, r) => {
2
2
  if (!t.has(e))
3
3
  throw TypeError("Cannot " + r);
4
4
  };
5
- var l = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), u = (e, t, r) => {
5
+ var l = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), d = (e, t, r) => {
6
6
  if (t.has(e))
7
7
  throw TypeError("Cannot add the same private member more than once");
8
8
  t instanceof WeakSet ? t.add(e) : t.set(e, r);
9
- }, h = (e, t, r, s) => (Y(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
9
+ }, p = (e, t, r, s) => (Y(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
10
10
  var f = (e, t, r) => (Y(e, t, "access private method"), r);
11
11
  const currentJsRuntime = function() {
12
12
  var e;
@@ -61,8 +61,8 @@ if (currentJsRuntime === "NODE") {
61
61
  r + i.byteLength
62
62
  ).arrayBuffer(), c = new Uint8Array(a);
63
63
  new Uint8Array(i.buffer).set(c);
64
- const d = c.byteLength;
65
- n.byobRequest.respond(d), r += d, r >= s.size && n.close();
64
+ const u = c.byteLength;
65
+ n.byobRequest.respond(u), r += u, r >= s.size && n.close();
66
66
  }
67
67
  });
68
68
  });
@@ -226,18 +226,40 @@ function extractPHPFunctionsFromStack(e) {
226
226
  return [];
227
227
  }
228
228
  }
229
+ const SleepFinished = Symbol("SleepFinished");
230
+ function sleep(e) {
231
+ return new Promise((t) => {
232
+ setTimeout(() => t(SleepFinished), e);
233
+ });
234
+ }
235
+ class AcquireTimeoutError extends Error {
236
+ constructor() {
237
+ super("Acquiring lock timed out");
238
+ }
239
+ }
229
240
  class Semaphore {
230
- constructor({ concurrency: t }) {
231
- this._running = 0, this.concurrency = t, this.queue = [];
241
+ constructor({ concurrency: t, timeout: r }) {
242
+ this._running = 0, this.concurrency = t, this.timeout = r, this.queue = [];
243
+ }
244
+ get remaining() {
245
+ return this.concurrency - this.running;
232
246
  }
233
247
  get running() {
234
248
  return this._running;
235
249
  }
236
250
  async acquire() {
237
251
  for (; ; )
238
- if (this._running >= this.concurrency)
239
- await new Promise((t) => this.queue.push(t));
240
- else {
252
+ if (this._running >= this.concurrency) {
253
+ const t = new Promise((r) => {
254
+ this.queue.push(r);
255
+ });
256
+ this.timeout !== void 0 ? await Promise.race([t, sleep(this.timeout)]).then(
257
+ (r) => {
258
+ if (r === SleepFinished)
259
+ throw new AcquireTimeoutError();
260
+ }
261
+ ) : await t;
262
+ } else {
241
263
  this._running++;
242
264
  let t = !1;
243
265
  return () => {
@@ -413,94 +435,6 @@ class PHPResponse {
413
435
  return new TextDecoder().decode(this.bytes);
414
436
  }
415
437
  }
416
- var v, T;
417
- class PHPBrowser {
418
- /**
419
- * @param server - The PHP server to browse.
420
- * @param config - The browser configuration.
421
- */
422
- constructor(t, r = {}) {
423
- u(this, v, void 0);
424
- u(this, T, void 0);
425
- this.requestHandler = t, h(this, v, {}), h(this, T, {
426
- handleRedirects: !1,
427
- maxRedirects: 4,
428
- ...r
429
- });
430
- }
431
- /**
432
- * Sends the request to the server.
433
- *
434
- * When cookies are present in the response, this method stores
435
- * them and sends them with any subsequent requests.
436
- *
437
- * When a redirection is present in the response, this method
438
- * follows it by discarding a response and sending a subsequent
439
- * request.
440
- *
441
- * @param request - The request.
442
- * @param redirects - Internal. The number of redirects handled so far.
443
- * @returns PHPRequestHandler response.
444
- */
445
- async request(t, r = 0) {
446
- const s = await this.requestHandler.request({
447
- ...t,
448
- headers: {
449
- ...t.headers,
450
- cookie: this.serializeCookies()
451
- }
452
- });
453
- if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), l(this, T).handleRedirects && s.headers.location && r < l(this, T).maxRedirects) {
454
- const n = new URL(
455
- s.headers.location[0],
456
- this.requestHandler.absoluteUrl
457
- );
458
- return this.request(
459
- {
460
- url: n.toString(),
461
- method: "GET",
462
- headers: {}
463
- },
464
- r + 1
465
- );
466
- }
467
- return s;
468
- }
469
- /** @inheritDoc */
470
- pathToInternalUrl(t) {
471
- return this.requestHandler.pathToInternalUrl(t);
472
- }
473
- /** @inheritDoc */
474
- internalUrlToPath(t) {
475
- return this.requestHandler.internalUrlToPath(t);
476
- }
477
- /** @inheritDoc */
478
- get absoluteUrl() {
479
- return this.requestHandler.absoluteUrl;
480
- }
481
- /** @inheritDoc */
482
- get documentRoot() {
483
- return this.requestHandler.documentRoot;
484
- }
485
- setCookies(t) {
486
- for (const r of t)
487
- try {
488
- if (!r.includes("="))
489
- continue;
490
- const s = r.indexOf("="), n = r.substring(0, s), i = r.substring(s + 1).split(";")[0];
491
- l(this, v)[n] = i;
492
- } catch (s) {
493
- console.error(s);
494
- }
495
- }
496
- serializeCookies() {
497
- const t = [];
498
- for (const r in l(this, v))
499
- t.push(`${r}=${l(this, v)[r]}`);
500
- return t.join("; ");
501
- }
502
- }
503
- v = new WeakMap(), T = new WeakMap();
504
438
  const DEFAULT_BASE_URL = "http://example.com";
505
439
  function toRelativeUrl(e) {
506
440
  return e.toString().substring(e.origin.length);
@@ -513,16 +447,16 @@ function ensurePathPrefix(e, t) {
513
447
  }
514
448
  async function encodeAsMultipart(e) {
515
449
  const t = `----${Math.random().toString(36).slice(2)}`, r = `multipart/form-data; boundary=${t}`, s = new TextEncoder(), n = [];
516
- for (const [c, d] of Object.entries(e))
450
+ for (const [c, u] of Object.entries(e))
517
451
  n.push(`--${t}\r
518
- `), n.push(`Content-Disposition: form-data; name="${c}"`), d instanceof File && n.push(`; filename="${d.name}"`), n.push(`\r
519
- `), d instanceof File && (n.push("Content-Type: application/octet-stream"), n.push(`\r
452
+ `), n.push(`Content-Disposition: form-data; name="${c}"`), u instanceof File && n.push(`; filename="${u.name}"`), n.push(`\r
453
+ `), u instanceof File && (n.push("Content-Type: application/octet-stream"), n.push(`\r
520
454
  `)), n.push(`\r
521
- `), d instanceof File ? n.push(await fileToUint8Array(d)) : n.push(d), n.push(`\r
455
+ `), u instanceof File ? n.push(await fileToUint8Array(u)) : n.push(u), n.push(`\r
522
456
  `);
523
457
  n.push(`--${t}--\r
524
458
  `);
525
- const i = n.reduce((c, d) => c + d.length, 0), o = new Uint8Array(i);
459
+ const i = n.reduce((c, u) => c + u.length, 0), o = new Uint8Array(i);
526
460
  let a = 0;
527
461
  for (const c of n)
528
462
  o.set(
@@ -539,7 +473,30 @@ function fileToUint8Array(e) {
539
473
  }, r.readAsArrayBuffer(e);
540
474
  });
541
475
  }
542
- var m, F, N, R, x, _, C, b, I, K, O, Z, U, X;
476
+ class HttpCookieStore {
477
+ constructor() {
478
+ this.cookies = {};
479
+ }
480
+ rememberCookiesFromResponseHeaders(t) {
481
+ if (t != null && t["set-cookie"])
482
+ for (const r of t["set-cookie"])
483
+ try {
484
+ if (!r.includes("="))
485
+ continue;
486
+ const s = r.indexOf("="), n = r.substring(0, s), i = r.substring(s + 1).split(";")[0];
487
+ this.cookies[n] = i;
488
+ } catch (s) {
489
+ console.error(s);
490
+ }
491
+ }
492
+ getCookieRequestHeader() {
493
+ const t = [];
494
+ for (const r in this.cookies)
495
+ t.push(`${r}=${this.cookies[r]}`);
496
+ return t.join("; ");
497
+ }
498
+ }
499
+ var m, b, A, P, S, _, T, v, F, H, Z, N, X, O, ee;
543
500
  class PHPRequestHandler {
544
501
  /**
545
502
  * @param php - The PHP instance.
@@ -552,7 +509,7 @@ class PHPRequestHandler {
552
509
  * @param fsPath - Absolute path of the static file to serve.
553
510
  * @returns The response.
554
511
  */
555
- u(this, I);
512
+ d(this, H);
556
513
  /**
557
514
  * Runs the requested PHP file with all the request and $_SERVER
558
515
  * superglobals populated.
@@ -560,7 +517,7 @@ class PHPRequestHandler {
560
517
  * @param request - The request.
561
518
  * @returns The response.
562
519
  */
563
- u(this, O);
520
+ d(this, N);
564
521
  /**
565
522
  * Resolve the requested path to the filesystem path of the requested PHP file.
566
523
  *
@@ -570,55 +527,120 @@ class PHPRequestHandler {
570
527
  * @throws {Error} If the requested path doesn't exist.
571
528
  * @returns The resolved filesystem path.
572
529
  */
573
- u(this, U);
574
- u(this, m, void 0);
575
- u(this, F, void 0);
576
- u(this, N, void 0);
577
- u(this, R, void 0);
578
- u(this, x, void 0);
579
- u(this, _, void 0);
580
- u(this, C, void 0);
581
- u(this, b, void 0);
582
- h(this, b, new Semaphore({ concurrency: 1 }));
530
+ d(this, O);
531
+ d(this, m, void 0);
532
+ d(this, b, void 0);
533
+ d(this, A, void 0);
534
+ d(this, P, void 0);
535
+ d(this, S, void 0);
536
+ d(this, _, void 0);
537
+ d(this, T, void 0);
538
+ d(this, v, void 0);
539
+ d(this, F, void 0);
540
+ p(this, v, new Semaphore({ concurrency: 1 }));
583
541
  const {
584
542
  documentRoot: s = "/www/",
585
543
  absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : "",
586
544
  rewriteRules: i = []
587
545
  } = r;
588
- this.php = t, h(this, m, s);
546
+ this.php = t, p(this, F, new HttpCookieStore()), p(this, m, s);
589
547
  const o = new URL(n);
590
- h(this, N, o.hostname), h(this, R, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), h(this, F, (o.protocol || "").replace(":", ""));
591
- const a = l(this, R) !== 443 && l(this, R) !== 80;
592
- h(this, x, [
593
- l(this, N),
594
- a ? `:${l(this, R)}` : ""
595
- ].join("")), h(this, _, o.pathname.replace(/\/+$/, "")), h(this, C, [
596
- `${l(this, F)}://`,
597
- l(this, x),
548
+ p(this, A, o.hostname), p(this, P, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), p(this, b, (o.protocol || "").replace(":", ""));
549
+ const a = l(this, P) !== 443 && l(this, P) !== 80;
550
+ p(this, S, [
551
+ l(this, A),
552
+ a ? `:${l(this, P)}` : ""
553
+ ].join("")), p(this, _, o.pathname.replace(/\/+$/, "")), p(this, T, [
554
+ `${l(this, b)}://`,
555
+ l(this, S),
598
556
  l(this, _)
599
557
  ].join("")), this.rewriteRules = i;
600
558
  }
601
- /** @inheritDoc */
559
+ /**
560
+ * Converts a path to an absolute URL based at the PHPRequestHandler
561
+ * root.
562
+ *
563
+ * @param path The server path to convert to an absolute URL.
564
+ * @returns The absolute URL.
565
+ */
602
566
  pathToInternalUrl(t) {
603
567
  return `${this.absoluteUrl}${t}`;
604
568
  }
605
- /** @inheritDoc */
569
+ /**
570
+ * Converts an absolute URL based at the PHPRequestHandler to a relative path
571
+ * without the server pathname and scope.
572
+ *
573
+ * @param internalUrl An absolute URL based at the PHPRequestHandler root.
574
+ * @returns The relative path.
575
+ */
606
576
  internalUrlToPath(t) {
607
577
  const r = new URL(t);
608
578
  return r.pathname.startsWith(l(this, _)) && (r.pathname = r.pathname.slice(l(this, _).length)), toRelativeUrl(r);
609
579
  }
610
580
  get isRequestRunning() {
611
- return l(this, b).running > 0;
581
+ return l(this, v).running > 0;
612
582
  }
613
- /** @inheritDoc */
583
+ /**
584
+ * The absolute URL of this PHPRequestHandler instance.
585
+ */
614
586
  get absoluteUrl() {
615
- return l(this, C);
587
+ return l(this, T);
616
588
  }
617
- /** @inheritDoc */
589
+ /**
590
+ * The directory in the PHP filesystem where the server will look
591
+ * for the files to serve. Default: `/var/www`.
592
+ */
618
593
  get documentRoot() {
619
594
  return l(this, m);
620
595
  }
621
- /** @inheritDoc */
596
+ /**
597
+ * Serves the request – either by serving a static file, or by
598
+ * dispatching it to the PHP runtime.
599
+ *
600
+ * The request() method mode behaves like a web server and only works if
601
+ * the PHP was initialized with a `requestHandler` option (which the online version
602
+ * of WordPress Playground does by default).
603
+ *
604
+ * In the request mode, you pass an object containing the request information
605
+ * (method, headers, body, etc.) and the path to the PHP file to run:
606
+ *
607
+ * ```ts
608
+ * const php = PHP.load('7.4', {
609
+ * requestHandler: {
610
+ * documentRoot: "/www"
611
+ * }
612
+ * })
613
+ * php.writeFile("/www/index.php", `<?php echo file_get_contents("php://input");`);
614
+ * const result = await php.request({
615
+ * method: "GET",
616
+ * headers: {
617
+ * "Content-Type": "text/plain"
618
+ * },
619
+ * body: "Hello world!",
620
+ * path: "/www/index.php"
621
+ * });
622
+ * // result.text === "Hello world!"
623
+ * ```
624
+ *
625
+ * The `request()` method cannot be used in conjunction with `cli()`.
626
+ *
627
+ * @example
628
+ * ```js
629
+ * const output = await php.request({
630
+ * method: 'GET',
631
+ * url: '/index.php',
632
+ * headers: {
633
+ * 'X-foo': 'bar',
634
+ * },
635
+ * body: {
636
+ * foo: 'bar',
637
+ * },
638
+ * });
639
+ * console.log(output.stdout); // "Hello world!"
640
+ * ```
641
+ *
642
+ * @param request - PHP Request data.
643
+ */
622
644
  async request(t) {
623
645
  const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL(
624
646
  // Remove the hash part of the URL as it's not meant for the server.
@@ -631,10 +653,10 @@ class PHPRequestHandler {
631
653
  ),
632
654
  this.rewriteRules
633
655
  ), i = joinPaths(l(this, m), n);
634
- return seemsLikeAPHPRequestHandlerPath(i) ? await f(this, O, Z).call(this, t, s) : f(this, I, K).call(this, i);
656
+ return seemsLikeAPHPRequestHandlerPath(i) ? await f(this, N, X).call(this, t, s) : f(this, H, Z).call(this, i);
635
657
  }
636
658
  }
637
- m = new WeakMap(), F = new WeakMap(), N = new WeakMap(), R = new WeakMap(), x = new WeakMap(), _ = new WeakMap(), C = new WeakMap(), b = new WeakMap(), I = new WeakSet(), K = function(t) {
659
+ m = new WeakMap(), b = new WeakMap(), A = new WeakMap(), P = new WeakMap(), S = new WeakMap(), _ = new WeakMap(), T = new WeakMap(), v = new WeakMap(), F = new WeakMap(), H = new WeakSet(), Z = function(t) {
638
660
  if (!this.php.fileExists(t))
639
661
  return new PHPResponse(
640
662
  404,
@@ -659,9 +681,9 @@ m = new WeakMap(), F = new WeakMap(), N = new WeakMap(), R = new WeakMap(), x =
659
681
  },
660
682
  r
661
683
  );
662
- }, O = new WeakSet(), Z = async function(t, r) {
684
+ }, N = new WeakSet(), X = async function(t, r) {
663
685
  var n;
664
- if (l(this, b).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php")
686
+ if (l(this, v).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php")
665
687
  return console.warn(
666
688
  "Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."
667
689
  ), new PHPResponse(
@@ -669,26 +691,23 @@ m = new WeakMap(), F = new WeakMap(), N = new WeakMap(), R = new WeakMap(), x =
669
691
  {},
670
692
  new TextEncoder().encode("502 Bad Gateway")
671
693
  );
672
- const s = await l(this, b).acquire();
694
+ const s = await l(this, v).acquire();
673
695
  try {
674
- this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", l(this, m)), this.php.addServerGlobalEntry(
675
- "HTTPS",
676
- l(this, C).startsWith("https://") ? "on" : ""
677
- );
678
696
  let i = "GET";
679
697
  const o = {
680
- host: l(this, x),
681
- ...normalizeHeaders(t.headers || {})
698
+ host: l(this, S),
699
+ ...normalizeHeaders(t.headers || {}),
700
+ cookie: l(this, F).getCookieRequestHeader()
682
701
  };
683
702
  let a = t.body;
684
703
  if (typeof a == "object" && !(a instanceof Uint8Array)) {
685
704
  i = "POST";
686
- const { bytes: d, contentType: p } = await encodeAsMultipart(a);
687
- a = d, o["content-type"] = p;
705
+ const { bytes: u, contentType: h } = await encodeAsMultipart(a);
706
+ a = u, o["content-type"] = h;
688
707
  }
689
708
  let c;
690
709
  try {
691
- c = f(this, U, X).call(this, decodeURIComponent(r.pathname));
710
+ c = f(this, O, ee).call(this, decodeURIComponent(r.pathname));
692
711
  } catch {
693
712
  return new PHPResponse(
694
713
  404,
@@ -696,21 +715,36 @@ m = new WeakMap(), F = new WeakMap(), N = new WeakMap(), R = new WeakMap(), x =
696
715
  new TextEncoder().encode("404 File not found")
697
716
  );
698
717
  }
699
- return await this.php.run({
700
- relativeUri: ensurePathPrefix(
701
- toRelativeUrl(r),
702
- l(this, _)
703
- ),
704
- protocol: l(this, F),
705
- method: t.method || i,
706
- body: a,
707
- scriptPath: c,
708
- headers: o
709
- });
718
+ try {
719
+ const u = await this.php.run({
720
+ relativeUri: ensurePathPrefix(
721
+ toRelativeUrl(r),
722
+ l(this, _)
723
+ ),
724
+ protocol: l(this, b),
725
+ method: t.method || i,
726
+ $_SERVER: {
727
+ REMOTE_ADDR: "127.0.0.1",
728
+ DOCUMENT_ROOT: l(this, m),
729
+ HTTPS: l(this, T).startsWith("https://") ? "on" : ""
730
+ },
731
+ body: a,
732
+ scriptPath: c,
733
+ headers: o
734
+ });
735
+ return l(this, F).rememberCookiesFromResponseHeaders(
736
+ u.headers
737
+ ), u;
738
+ } catch (u) {
739
+ const h = u;
740
+ if (h != null && h.response)
741
+ return h.response;
742
+ throw u;
743
+ }
710
744
  } finally {
711
745
  s();
712
746
  }
713
- }, U = new WeakSet(), X = function(t) {
747
+ }, O = new WeakSet(), ee = function(t) {
714
748
  let r = removePathPrefix(t, l(this, _));
715
749
  r = applyRewriteRules(r, this.rewriteRules), r.includes(".php") ? r = r.split(".php")[0] + ".php" : this.php.isDir(`${l(this, m)}${r}`) ? (r.endsWith("/") || (r = `${r}/`), r = `${r}index.php`) : r = "/index.php";
716
750
  const s = `${l(this, m)}${r}`;
@@ -754,6 +788,38 @@ function inferMimeType(e) {
754
788
  case "txt":
755
789
  case "md":
756
790
  return "text/plain";
791
+ case "pdf":
792
+ return "application/pdf";
793
+ case "webp":
794
+ return "image/webp";
795
+ case "mp3":
796
+ return "audio/mpeg";
797
+ case "mp4":
798
+ return "video/mp4";
799
+ case "csv":
800
+ return "text/csv";
801
+ case "xls":
802
+ return "application/vnd.ms-excel";
803
+ case "xlsx":
804
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
805
+ case "doc":
806
+ return "application/msword";
807
+ case "docx":
808
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
809
+ case "ppt":
810
+ return "application/vnd.ms-powerpoint";
811
+ case "pptx":
812
+ return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
813
+ case "zip":
814
+ return "application/zip";
815
+ case "rar":
816
+ return "application/x-rar-compressed";
817
+ case "tar":
818
+ return "application/x-tar";
819
+ case "gz":
820
+ return "application/gzip";
821
+ case "7z":
822
+ return "application/x-7z-compressed";
757
823
  default:
758
824
  return "application-octet-stream";
759
825
  }
@@ -866,8 +932,8 @@ function rethrowFileSystemError(e = "") {
866
932
  } catch (a) {
867
933
  const c = typeof a == "object" ? a == null ? void 0 : a.errno : null;
868
934
  if (c in FileErrorCodes) {
869
- const d = FileErrorCodes[c], p = typeof o[0] == "string" ? o[0] : null, P = p !== null ? e.replaceAll("{path}", p) : e;
870
- throw new Error(`${P}: ${d}`, {
935
+ const u = FileErrorCodes[c], h = typeof o[0] == "string" ? o[0] : null, g = h !== null ? e.replaceAll("{path}", h) : e;
936
+ throw new Error(`${g}: ${u}`, {
871
937
  cause: a
872
938
  });
873
939
  }
@@ -890,7 +956,12 @@ var __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyD
890
956
  return s && n && __defProp(t, r, n), n;
891
957
  };
892
958
  const STRING = "string", NUMBER = "number", __private__dont__use = Symbol("__private__dont__use");
893
- var S, k, A, y, w, g, E, H, M, ee, B, te, L, re, D, se, q, ne, $, ie, W, oe, j, ae, z, le, G, ce, J, ue, Q, de;
959
+ class PHPExecutionFailureError extends Error {
960
+ constructor(t, r, s) {
961
+ super(t), this.response = r, this.source = s;
962
+ }
963
+ }
964
+ var R, x, k, y, w, E, C, I, te, M, re, U, se, B, ne, L, ie, D, oe, $, ae, q, le, W, ce, j, ue, z, de, G, he, J, pe, V, fe, Q, _e;
894
965
  class BasePHP {
895
966
  /**
896
967
  * Initializes a PHP runtime.
@@ -900,29 +971,38 @@ class BasePHP {
900
971
  * @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
901
972
  */
902
973
  constructor(e, t) {
903
- u(this, M);
904
- u(this, B);
905
- u(this, L);
906
- u(this, D);
907
- u(this, q);
908
- u(this, $);
909
- u(this, W);
910
- u(this, j);
911
- u(this, z);
912
- u(this, G);
913
- u(this, J);
914
- u(this, Q);
915
- u(this, S, void 0);
916
- u(this, k, void 0);
917
- u(this, A, void 0);
918
- u(this, y, void 0);
919
- u(this, w, void 0);
920
- u(this, g, void 0);
921
- u(this, E, void 0);
922
- u(this, H, void 0);
923
- h(this, S, []), h(this, y, !1), h(this, w, null), h(this, g, {}), h(this, E, /* @__PURE__ */ new Map()), h(this, H, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
924
- new PHPRequestHandler(this, t)
925
- ));
974
+ /**
975
+ * Prepares the $_SERVER entries for the PHP runtime.
976
+ *
977
+ * @param defaults Default entries to include in $_SERVER.
978
+ * @param headers HTTP headers to include in $_SERVER (as HTTP_ prefixed entries).
979
+ * @param port HTTP port, used to determine infer $_SERVER['HTTPS'] value if none
980
+ * was provided.
981
+ * @returns Computed $_SERVER entries.
982
+ */
983
+ d(this, I);
984
+ d(this, M);
985
+ d(this, U);
986
+ d(this, B);
987
+ d(this, L);
988
+ d(this, D);
989
+ d(this, $);
990
+ d(this, q);
991
+ d(this, W);
992
+ d(this, j);
993
+ d(this, z);
994
+ d(this, G);
995
+ d(this, J);
996
+ d(this, V);
997
+ d(this, Q);
998
+ d(this, R, void 0);
999
+ d(this, x, void 0);
1000
+ d(this, k, void 0);
1001
+ d(this, y, void 0);
1002
+ d(this, w, void 0);
1003
+ d(this, E, void 0);
1004
+ d(this, C, void 0);
1005
+ p(this, R, []), p(this, y, !1), p(this, w, null), p(this, E, /* @__PURE__ */ new Map()), p(this, C, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPRequestHandler(this, t));
926
1006
  }
927
1007
  addEventListener(e, t) {
928
1008
  l(this, E).has(e) || l(this, E).set(e, /* @__PURE__ */ new Set()), l(this, E).get(e).add(t);
@@ -939,7 +1019,7 @@ class BasePHP {
939
1019
  }
940
1020
  /** @inheritDoc */
941
1021
  async onMessage(e) {
942
- l(this, H).push(e);
1022
+ l(this, C).push(e);
943
1023
  }
944
1024
  /** @inheritDoc */
945
1025
  async setSpawnHandler(handler) {
@@ -947,21 +1027,19 @@ class BasePHP {
947
1027
  }
948
1028
  /** @inheritDoc */
949
1029
  get absoluteUrl() {
950
- return this.requestHandler.requestHandler.absoluteUrl;
1030
+ return this.requestHandler.absoluteUrl;
951
1031
  }
952
1032
  /** @inheritDoc */
953
1033
  get documentRoot() {
954
- return this.requestHandler.requestHandler.documentRoot;
1034
+ return this.requestHandler.documentRoot;
955
1035
  }
956
1036
  /** @inheritDoc */
957
1037
  pathToInternalUrl(e) {
958
- return this.requestHandler.requestHandler.pathToInternalUrl(e);
1038
+ return this.requestHandler.pathToInternalUrl(e);
959
1039
  }
960
1040
  /** @inheritDoc */
961
1041
  internalUrlToPath(e) {
962
- return this.requestHandler.requestHandler.internalUrlToPath(
963
- e
964
- );
1042
+ return this.requestHandler.internalUrlToPath(e);
965
1043
  }
966
1044
  initializeRuntime(e) {
967
1045
  if (this[__private__dont__use])
@@ -970,13 +1048,13 @@ class BasePHP {
970
1048
  if (!t)
971
1049
  throw new Error("Invalid PHP runtime id.");
972
1050
  this[__private__dont__use] = t, t.onMessage = async (r) => {
973
- for (const s of l(this, H)) {
1051
+ for (const s of l(this, C)) {
974
1052
  const n = await s(r);
975
1053
  if (n)
976
1054
  return n;
977
1055
  }
978
1056
  return "";
979
- }, h(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
1057
+ }, p(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
980
1058
  type: "runtime.initialized"
981
1059
  });
982
1060
  }
@@ -991,13 +1069,13 @@ class BasePHP {
991
1069
  throw new Error(
992
1070
  "Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
993
1071
  );
994
- h(this, A, e);
1072
+ p(this, k, e);
995
1073
  }
996
1074
  /** @inheritDoc */
997
1075
  setPhpIniPath(e) {
998
1076
  if (l(this, y))
999
1077
  throw new Error("Cannot set PHP ini path after calling run().");
1000
- h(this, k, e), this[__private__dont__use].ccall(
1078
+ p(this, x, e), this[__private__dont__use].ccall(
1001
1079
  "wasm_set_phpini_path",
1002
1080
  null,
1003
1081
  ["string"],
@@ -1008,42 +1086,47 @@ class BasePHP {
1008
1086
  setPhpIniEntry(e, t) {
1009
1087
  if (l(this, y))
1010
1088
  throw new Error("Cannot set PHP ini entries after calling run().");
1011
- l(this, S).push([e, t]);
1089
+ l(this, R).push([e, t]);
1012
1090
  }
1013
1091
  /** @inheritDoc */
1014
1092
  chdir(e) {
1015
1093
  this[__private__dont__use].FS.chdir(e);
1016
1094
  }
1017
1095
  /** @inheritDoc */
1018
- async request(e, t) {
1096
+ async request(e) {
1019
1097
  if (!this.requestHandler)
1020
1098
  throw new Error("No request handler available.");
1021
- return this.requestHandler.request(e, t);
1099
+ return this.requestHandler.request(e);
1022
1100
  }
1023
1101
  /** @inheritDoc */
1024
1102
  async run(e) {
1025
1103
  const t = await this.semaphore.acquire();
1026
1104
  let r;
1027
1105
  try {
1028
- if (l(this, y) || (f(this, M, ee).call(this), h(this, y, !0)), e.scriptPath && !this.fileExists(e.scriptPath))
1106
+ if (l(this, y) || (f(this, M, re).call(this), p(this, y, !0)), e.scriptPath && !this.fileExists(e.scriptPath))
1029
1107
  throw new Error(
1030
1108
  `The script path "${e.scriptPath}" does not exist.`
1031
1109
  );
1032
- f(this, j, ae).call(this, e.scriptPath || ""), f(this, L, re).call(this, e.relativeUri || ""), f(this, q, ne).call(this, e.method || "GET");
1033
- const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443";
1034
- f(this, D, se).call(this, n, e.protocol || "http"), f(this, $, ie).call(this, s), e.body && (r = f(this, W, oe).call(this, e.body)), typeof e.code == "string" && f(this, J, ue).call(this, " ?>" + e.code), f(this, z, le).call(this);
1035
- const i = e.env || {};
1036
- for (const a in i)
1037
- f(this, G, ce).call(this, a, i[a]);
1038
- const o = await f(this, Q, de).call(this);
1039
- if (o.exitCode !== 0) {
1040
- console.warn("PHP.run() output was:", o.text);
1041
- const a = new Error(
1042
- `PHP.run() failed with exit code ${o.exitCode} and the following output: ` + o.errors
1110
+ f(this, z, de).call(this, e.scriptPath || ""), f(this, B, ne).call(this, e.relativeUri || ""), f(this, q, le).call(this, e.method || "GET");
1111
+ const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443", i = f(this, $, ae).call(this, n, e.protocol || "http");
1112
+ f(this, L, ie).call(this, n), f(this, D, oe).call(this, i), f(this, W, ce).call(this, s), e.body && (r = f(this, j, ue).call(this, e.body)), typeof e.code == "string" && f(this, V, fe).call(this, " ?>" + e.code);
1113
+ const o = f(this, I, te).call(this, e.$_SERVER, s, i);
1114
+ for (const u in o)
1115
+ f(this, G, he).call(this, u, o[u]);
1116
+ const a = e.env || {};
1117
+ for (const u in a)
1118
+ f(this, J, pe).call(this, u, a[u]);
1119
+ const c = await f(this, Q, _e).call(this);
1120
+ if (c.exitCode !== 0) {
1121
+ console.warn("PHP.run() output was:", c.text);
1122
+ const u = new PHPExecutionFailureError(
1123
+ `PHP.run() failed with exit code ${c.exitCode} and the following output: ` + c.errors,
1124
+ c,
1125
+ "request"
1043
1126
  );
1044
- throw a.response = o, a.source = "request", console.error(a), a;
1127
+ throw console.error(u), u;
1045
1128
  }
1046
- return o;
1129
+ return c;
1047
1130
  } catch (s) {
1048
1131
  throw this.dispatchEvent({
1049
1132
  type: "request.error",
@@ -1061,9 +1144,6 @@ class BasePHP {
1061
1144
  }
1062
1145
  }
1063
1146
  }
1064
- addServerGlobalEntry(e, t) {
1065
- l(this, g)[e] = t;
1066
- }
1067
1147
  defineConstant(e, t) {
1068
1148
  let r = {};
1069
1149
  try {
@@ -1151,17 +1231,18 @@ class BasePHP {
1151
1231
  * interrupting the operations of this PHP instance.
1152
1232
  *
1153
1233
  * @param runtime
1234
+ * @param cwd. Internal, the VFS path to recreate in the new runtime.
1235
+ * This arg is temporary and will be removed once BasePHP
1236
+ * is fully decoupled from the request handler and
1237
+ * accepts a constructor-level cwd argument.
1154
1238
  */
1155
- hotSwapPHPRuntime(e) {
1156
- const t = this[__private__dont__use].FS;
1239
+ hotSwapPHPRuntime(e, t) {
1240
+ const r = this[__private__dont__use].FS;
1157
1241
  try {
1158
1242
  this.exit();
1159
1243
  } catch {
1160
1244
  }
1161
- if (this.initializeRuntime(e), l(this, k) && this.setPhpIniPath(l(this, k)), l(this, A) && this.setSapiName(l(this, A)), this.requestHandler) {
1162
- const r = this.documentRoot;
1163
- copyFS(t, this[__private__dont__use].FS, r);
1164
- }
1245
+ this.initializeRuntime(e), l(this, x) && this.setPhpIniPath(l(this, x)), l(this, k) && this.setSapiName(l(this, k)), t && copyFS(r, this[__private__dont__use].FS, t);
1165
1246
  }
1166
1247
  exit(e = 0) {
1167
1248
  this.dispatchEvent({
@@ -1171,10 +1252,20 @@ class BasePHP {
1171
1252
  this[__private__dont__use]._exit(e);
1172
1253
  } catch {
1173
1254
  }
1174
- h(this, y, !1), h(this, w, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1255
+ p(this, y, !1), p(this, w, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1175
1256
  }
1176
1257
  }
1177
- S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w = new WeakMap(), g = new WeakMap(), E = new WeakMap(), H = new WeakMap(), M = new WeakSet(), ee = function() {
1258
+ R = new WeakMap(), x = new WeakMap(), k = new WeakMap(), y = new WeakMap(), w = new WeakMap(), E = new WeakMap(), C = new WeakMap(), I = new WeakSet(), te = function(e, t, r) {
1259
+ const s = {
1260
+ ...e || {}
1261
+ };
1262
+ s.HTTPS = s.HTTPS || r === 443 ? "on" : "off";
1263
+ for (const n in t) {
1264
+ let i = "HTTP_";
1265
+ ["content-type", "content-length"].includes(n.toLowerCase()) && (i = ""), s[`${i}${n.toUpperCase().replace(/-/g, "_")}`] = t[n];
1266
+ }
1267
+ return s;
1268
+ }, M = new WeakSet(), re = function() {
1178
1269
  if (this.setPhpIniEntry("auto_prepend_file", "/internal/consts.php"), this.fileExists("/internal/consts.php") || this.writeFile(
1179
1270
  "/internal/consts.php",
1180
1271
  `<?php
@@ -1186,8 +1277,8 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1186
1277
  }
1187
1278
  }
1188
1279
  }`
1189
- ), l(this, S).length > 0) {
1190
- const e = l(this, S).map(([t, r]) => `${t}=${r}`).join(`
1280
+ ), l(this, R).length > 0) {
1281
+ const e = l(this, R).map(([t, r]) => `${t}=${r}`).join(`
1191
1282
  `) + `
1192
1283
 
1193
1284
  `;
@@ -1199,7 +1290,7 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1199
1290
  );
1200
1291
  }
1201
1292
  this[__private__dont__use].ccall("php_wasm_init", null, [], []);
1202
- }, B = new WeakSet(), te = function() {
1293
+ }, U = new WeakSet(), se = function() {
1203
1294
  const e = "/internal/headers.json";
1204
1295
  if (!this.fileExists(e))
1205
1296
  throw new Error(
@@ -1216,7 +1307,7 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1216
1307
  headers: r,
1217
1308
  httpStatusCode: t.status
1218
1309
  };
1219
- }, L = new WeakSet(), re = function(e) {
1310
+ }, B = new WeakSet(), ne = function(e) {
1220
1311
  if (this[__private__dont__use].ccall(
1221
1312
  "wasm_set_request_uri",
1222
1313
  null,
@@ -1231,32 +1322,35 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1231
1322
  [t]
1232
1323
  );
1233
1324
  }
1234
- }, D = new WeakSet(), se = function(e, t) {
1325
+ }, L = new WeakSet(), ie = function(e) {
1235
1326
  this[__private__dont__use].ccall(
1236
1327
  "wasm_set_request_host",
1237
1328
  null,
1238
1329
  [STRING],
1239
1330
  [e]
1240
1331
  );
1332
+ }, D = new WeakSet(), oe = function(e) {
1333
+ this[__private__dont__use].ccall(
1334
+ "wasm_set_request_port",
1335
+ null,
1336
+ [NUMBER],
1337
+ [e]
1338
+ );
1339
+ }, $ = new WeakSet(), ae = function(e, t) {
1241
1340
  let r;
1242
1341
  try {
1243
1342
  r = parseInt(new URL(e).port, 10);
1244
1343
  } catch {
1245
1344
  }
1246
- (!r || isNaN(r) || r === 80) && (r = t === "https" ? 443 : 80), this[__private__dont__use].ccall(
1247
- "wasm_set_request_port",
1248
- null,
1249
- [NUMBER],
1250
- [r]
1251
- ), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on");
1252
- }, q = new WeakSet(), ne = function(e) {
1345
+ return (!r || isNaN(r) || r === 80) && (r = t === "https" ? 443 : 80), r;
1346
+ }, q = new WeakSet(), le = function(e) {
1253
1347
  this[__private__dont__use].ccall(
1254
1348
  "wasm_set_request_method",
1255
1349
  null,
1256
1350
  [STRING],
1257
1351
  [e]
1258
1352
  );
1259
- }, $ = new WeakSet(), ie = function(e) {
1353
+ }, W = new WeakSet(), ce = function(e) {
1260
1354
  e.cookie && this[__private__dont__use].ccall(
1261
1355
  "wasm_set_cookies",
1262
1356
  null,
@@ -1273,14 +1367,7 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1273
1367
  [NUMBER],
1274
1368
  [parseInt(e["content-length"], 10)]
1275
1369
  );
1276
- for (const t in e) {
1277
- let r = "HTTP_";
1278
- ["content-type", "content-length"].includes(t.toLowerCase()) && (r = ""), this.addServerGlobalEntry(
1279
- `${r}${t.toUpperCase().replace(/-/g, "_")}`,
1280
- e[t]
1281
- );
1282
- }
1283
- }, W = new WeakSet(), oe = function(e) {
1370
+ }, j = new WeakSet(), ue = function(e) {
1284
1371
  let t, r;
1285
1372
  typeof e == "string" ? (console.warn(
1286
1373
  "Passing a string as the request body is deprecated. Please use a Uint8Array instead. See https://github.com/WordPress/wordpress-playground/issues/997 for more details"
@@ -1303,45 +1390,44 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1303
1390
  [NUMBER],
1304
1391
  [r]
1305
1392
  ), s;
1306
- }, j = new WeakSet(), ae = function(e) {
1393
+ }, z = new WeakSet(), de = function(e) {
1307
1394
  this[__private__dont__use].ccall(
1308
1395
  "wasm_set_path_translated",
1309
1396
  null,
1310
1397
  [STRING],
1311
1398
  [e]
1312
1399
  );
1313
- }, z = new WeakSet(), le = function() {
1314
- for (const e in l(this, g))
1315
- this[__private__dont__use].ccall(
1316
- "wasm_add_SERVER_entry",
1317
- null,
1318
- [STRING, STRING],
1319
- [e, l(this, g)[e]]
1320
- );
1321
- }, G = new WeakSet(), ce = function(e, t) {
1400
+ }, G = new WeakSet(), he = function(e, t) {
1401
+ this[__private__dont__use].ccall(
1402
+ "wasm_add_SERVER_entry",
1403
+ null,
1404
+ [STRING, STRING],
1405
+ [e, t]
1406
+ );
1407
+ }, J = new WeakSet(), pe = function(e, t) {
1322
1408
  this[__private__dont__use].ccall(
1323
1409
  "wasm_add_ENV_entry",
1324
1410
  null,
1325
1411
  [STRING, STRING],
1326
1412
  [e, t]
1327
1413
  );
1328
- }, J = new WeakSet(), ue = function(e) {
1414
+ }, V = new WeakSet(), fe = function(e) {
1329
1415
  this[__private__dont__use].ccall(
1330
1416
  "wasm_set_php_code",
1331
1417
  null,
1332
1418
  [STRING],
1333
1419
  [e]
1334
1420
  );
1335
- }, Q = new WeakSet(), de = async function() {
1421
+ }, Q = new WeakSet(), _e = async function() {
1336
1422
  var n;
1337
1423
  let e, t;
1338
1424
  try {
1339
1425
  e = await new Promise((i, o) => {
1340
1426
  var c;
1341
- t = (d) => {
1342
- console.error(d), console.error(d.error);
1343
- const p = new Error("Rethrown");
1344
- p.cause = d.error, p.betterMessage = d.message, o(p);
1427
+ t = (u) => {
1428
+ console.error(u), console.error(u.error);
1429
+ const h = new Error("Rethrown");
1430
+ h.cause = u.error, h.betterMessage = u.message, o(h);
1345
1431
  }, (c = l(this, w)) == null || c.addEventListener(
1346
1432
  "error",
1347
1433
  t
@@ -1356,8 +1442,8 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1356
1442
  return a instanceof Promise ? a.then(i, o) : i(a);
1357
1443
  });
1358
1444
  } catch (i) {
1359
- for (const d in this)
1360
- typeof this[d] == "function" && (this[d] = () => {
1445
+ for (const u in this)
1446
+ typeof this[u] == "function" && (this[u] = () => {
1361
1447
  throw new Error(
1362
1448
  "PHP runtime has crashed – see the earlier error for details."
1363
1449
  );
@@ -1366,11 +1452,11 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w =
1366
1452
  const o = i, a = "betterMessage" in o ? o.betterMessage : o.message, c = new Error(a);
1367
1453
  throw c.cause = o, console.error(c), c;
1368
1454
  } finally {
1369
- (n = l(this, w)) == null || n.removeEventListener("error", t), h(this, g, {});
1455
+ (n = l(this, w)) == null || n.removeEventListener("error", t);
1370
1456
  }
1371
- const { headers: r, httpStatusCode: s } = f(this, B, te).call(this);
1457
+ const { headers: r, httpStatusCode: s } = f(this, U, se).call(this);
1372
1458
  return new PHPResponse(
1373
- s,
1459
+ e === 0 ? s : 500,
1374
1460
  r,
1375
1461
  this.readFileAsBuffer("/internal/stdout"),
1376
1462
  this.readFileAsText("/internal/stderr"),
@@ -1435,32 +1521,32 @@ function journalFSEvents(e, t, r = () => {
1435
1521
  }) {
1436
1522
  function s() {
1437
1523
  t = normalizePath(t);
1438
- const i = e[__private__dont__use].FS, o = createFSHooks(i, (p) => {
1439
- if (p.path.startsWith(t))
1440
- r(p);
1441
- else if (p.operation === "RENAME" && p.toPath.startsWith(t))
1442
- for (const P of recordExistingPath(
1524
+ const i = e[__private__dont__use].FS, o = createFSHooks(i, (h) => {
1525
+ if (h.path.startsWith(t))
1526
+ r(h);
1527
+ else if (h.operation === "RENAME" && h.toPath.startsWith(t))
1528
+ for (const g of recordExistingPath(
1443
1529
  e,
1444
- p.path,
1445
- p.toPath
1530
+ h.path,
1531
+ h.toPath
1446
1532
  ))
1447
- r(P);
1533
+ r(g);
1448
1534
  }), a = {};
1449
- for (const [p] of Object.entries(o))
1450
- a[p] = i[p];
1535
+ for (const [h] of Object.entries(o))
1536
+ a[h] = i[h];
1451
1537
  function c() {
1452
- for (const [p, P] of Object.entries(o))
1453
- i[p] = function(...V) {
1454
- return P(...V), a[p].apply(this, V);
1538
+ for (const [h, g] of Object.entries(o))
1539
+ i[h] = function(...K) {
1540
+ return g(...K), a[h].apply(this, K);
1455
1541
  };
1456
1542
  }
1457
- function d() {
1458
- for (const [p, P] of Object.entries(a))
1459
- e[__private__dont__use].FS[p] = P;
1543
+ function u() {
1544
+ for (const [h, g] of Object.entries(a))
1545
+ e[__private__dont__use].FS[h] = g;
1460
1546
  }
1461
1547
  e[__private__dont__use].journal = {
1462
1548
  bind: c,
1463
- unbind: d
1549
+ unbind: u
1464
1550
  }, c();
1465
1551
  }
1466
1552
  e.addEventListener("runtime.initialized", s), e[__private__dont__use] && s();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/fs-journal",
3
- "version": "0.6.15",
3
+ "version": "0.7.0",
4
4
  "description": "Bindings to journal the PHP filesystem",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "main": "./index.cjs",
37
37
  "module": "./index.js",
38
38
  "license": "GPL-2.0-or-later",
39
- "gitHead": "e05126da329a26535905b0ab65415d20118f0197",
39
+ "gitHead": "c5eba3d709f2821c4303521e8c81b962e3bcca23",
40
40
  "engines": {
41
41
  "node": ">=18.18.0",
42
42
  "npm": ">=8.11.0"